diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 190b5038c3f8fac135d53ec38e75a2b6b1ffb812..0000000000000000000000000000000000000000
--- a/.babelrc
+++ /dev/null
@@ -1,66 +0,0 @@
-{
-  "presets": [
-    "react",
-    [
-      "env",
-      {
-        "exclude": ["transform-async-to-generator", "transform-regenerator"],
-        "loose": true,
-        "modules": false,
-        "targets": {
-          "browsers": ["last 2 versions", "IE >= 11", "iOS >= 9"]
-        }
-      }
-    ]
-  ],
-  "plugins": [
-    "syntax-dynamic-import",
-    ["transform-object-rest-spread", { "useBuiltIns": true }],
-    "transform-decorators-legacy",
-    "transform-class-properties",
-    [
-      "react-intl",
-      {
-        "messagesDir": "./build/messages"
-      }
-    ],
-    "preval"
-  ],
-  "env": {
-    "development": {
-      "plugins": [
-        "transform-react-jsx-source",
-        "transform-react-jsx-self"
-      ]
-    },
-    "production": {
-      "plugins": [
-        "lodash",
-        [
-          "transform-react-remove-prop-types",
-          {
-            "mode": "remove",
-            "removeImport": true,
-            "additionalLibraries": [
-              "react-immutable-proptypes"
-            ]
-          }
-        ],
-        "transform-react-inline-elements",
-        [
-          "transform-runtime",
-          {
-            "helpers": true,
-            "polyfill": false,
-            "regenerator": false
-          }
-        ]
-      ]
-    },
-    "test": {
-      "plugins": [
-        "transform-es2015-modules-commonjs"
-      ]
-    }
-  }
-}
diff --git a/.buildpacks b/.buildpacks
index c232c712f75139ebfad1686ae162c23f4213f0a1..3450683ce84ce6592d034ed2b4d7f7c29259c657 100644
--- a/.buildpacks
+++ b/.buildpacks
@@ -1,3 +1,4 @@
 https://github.com/heroku/heroku-buildpack-apt
+https://github.com/Scalingo/ffmpeg-buildpack
 https://github.com/Scalingo/nodejs-buildpack
 https://github.com/Scalingo/ruby-buildpack
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 2a1c842536d0770708e74eac03217b07ac29bb06..e8bfde2994629f53eb8e038586ed38e6247f7217 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -3,7 +3,7 @@ version: 2
 aliases:
   - &defaults
     docker:
-      - image: circleci/ruby:2.5.1-stretch-node
+      - image: circleci/ruby:2.6.0-stretch-node
         environment: &ruby_environment
           BUNDLE_APP_CONFIG: ./.bundle/
           DB_HOST: localhost
@@ -13,6 +13,9 @@ aliases:
           ALLOW_NOPAM: true
           CONTINUOUS_INTEGRATION: true
           DISABLE_SIMPLECOV: true
+          PAM_ENABLED: true
+          PAM_DEFAULT_SERVICE: pam_test
+          PAM_CONTROLLED_SERVICE: pam_test_controlled
     working_directory: ~/projects/mastodon/
 
   - &attach_workspace
@@ -64,12 +67,17 @@ aliases:
 
         - run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
         - *restore_ruby_dependencies
-        - run: bundle install --clean --jobs 16 --path ./vendor/bundle/ --retry 3 --with pam_authentication --without development production
+        - run: bundle install --clean --jobs 16 --path ./vendor/bundle/ --retry 3 --with pam_authentication --without development production && bundle clean
         - save_cache:
             key: v2-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }}
             paths:
               - ./.bundle/
               - ./vendor/bundle/
+        - persist_to_workspace:
+            root: ~/projects/
+            paths:
+                - ./mastodon/.bundle/
+                - ./mastodon/vendor/bundle/
 
   - &test_steps
       steps:
@@ -78,15 +86,6 @@ aliases:
         - *install_system_dependencies
         - run: sudo apt-get install -y ffmpeg
 
-        - run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
-        - *restore_ruby_dependencies
-
-        - restore_cache:
-            keys:
-              - precompiled-assets-{{ .Branch }}-{{ .Revision }}
-              - precompiled-assets-{{ .Branch }}-
-              - precompiled-assets-
-
         - run:
             name: Prepare Tests
             command: ./bin/rails parallel:create parallel:load_schema parallel:prepare
@@ -99,21 +98,21 @@ jobs:
     <<: *defaults
     <<: *install_steps
 
-  install-ruby2.5:
+  install-ruby2.6:
     <<: *defaults
     <<: *install_ruby_dependencies
 
-  install-ruby2.4:
+  install-ruby2.5:
     <<: *defaults
     docker:
-      - image: circleci/ruby:2.4.4-stretch-node
+      - image: circleci/ruby:2.5.3-stretch-node
         environment: *ruby_environment
     <<: *install_ruby_dependencies
 
-  install-ruby2.3:
+  install-ruby2.4:
     <<: *defaults
     docker:
-      - image: circleci/ruby:2.3.7-stretch-node
+      - image: circleci/ruby:2.4.5-stretch-node
         environment: *ruby_environment
     <<: *install_ruby_dependencies
 
@@ -122,52 +121,50 @@ jobs:
     steps:
       - *attach_workspace
       - *install_system_dependencies
-      - run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
-      - *restore_ruby_dependencies
       - run: ./bin/rails assets:precompile
-      - save_cache:
-          key: precompiled-assets-{{ .Branch }}-{{ .Revision }}
+      - persist_to_workspace:
+          root: ~/projects/
           paths:
-            - ./public/assets
-            - ./public/packs-test/
+              - ./mastodon/public/assets
+              - ./mastodon/public/packs-test/
 
-  test-ruby2.5:
+  test-ruby2.6:
     <<: *defaults
     docker:
-      - image: circleci/ruby:2.5.1-stretch-node
+      - image: circleci/ruby:2.6.0-stretch-node
         environment: *ruby_environment
-      - image: circleci/postgres:10.3-alpine
+      - image: circleci/postgres:10.6-alpine
         environment:
           POSTGRES_USER: root
-      - image: circleci/redis:4.0.9-alpine
+      - image: circleci/redis:5.0.3-alpine3.8
     <<: *test_steps
 
-  test-ruby2.4:
+  test-ruby2.5:
     <<: *defaults
     docker:
-      - image: circleci/ruby:2.4.4-stretch-node
+      - image: circleci/ruby:2.5.3-stretch-node
         environment: *ruby_environment
-      - image: circleci/postgres:10.3-alpine
+      - image: circleci/postgres:10.6-alpine
         environment:
           POSTGRES_USER: root
-      - image: circleci/redis:4.0.9-alpine
+      - image: circleci/redis:4.0.12-alpine
     <<: *test_steps
 
-  test-ruby2.3:
+  test-ruby2.4:
     <<: *defaults
     docker:
-      - image: circleci/ruby:2.3.7-stretch-node
+      - image: circleci/ruby:2.4.5-stretch-node
         environment: *ruby_environment
-      - image: circleci/postgres:10.3-alpine
+      - image: circleci/postgres:10.6-alpine
         environment:
           POSTGRES_USER: root
-      - image: circleci/redis:4.0.9-alpine
+      - image: circleci/redis:4.0.12-alpine
     <<: *test_steps
 
   test-webui:
     <<: *defaults
     docker:
-      - image: circleci/node:8.11.1-stretch
+      - image: circleci/node:8.15.0-stretch
     steps:
       - *attach_workspace
       - run: ./bin/retry yarn test:jest
@@ -176,28 +173,34 @@ jobs:
     <<: *defaults
     steps:
       - *attach_workspace
-      - run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
-      - *restore_ruby_dependencies
       - 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 check-consistent-interpolations
 
 workflows:
   version: 2
   build-and-test:
     jobs:
       - install
-      - install-ruby2.5:
+      - install-ruby2.6:
           requires:
             - install
-      - install-ruby2.4:
+      - install-ruby2.5:
           requires:
             - install
-      - install-ruby2.3:
+            - install-ruby2.6
+      - install-ruby2.4:
           requires:
             - install
+            - install-ruby2.6
       - build:
           requires:
-            - install-ruby2.5
+            - install-ruby2.6
+      - test-ruby2.6:
+          requires:
+            - install-ruby2.6
+            - build
       - test-ruby2.5:
           requires:
             - install-ruby2.5
@@ -206,13 +209,9 @@ workflows:
           requires:
             - install-ruby2.4
             - build
-      - test-ruby2.3:
-          requires:
-            - install-ruby2.3
-            - build
       - test-webui:
           requires:
             - install
       - check-i18n:
           requires:
-            - install-ruby2.5
+            - install-ruby2.6
diff --git a/.codeclimate.yml b/.codeclimate.yml
index 58f6b3de4d90dc5d21cfad8e3b688e98d567be2b..a704597649c32e233953cd0e9851c64fbff15256 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -27,7 +27,7 @@ plugins:
     enabled: true
   eslint:
     enabled: true
-    channel: eslint-4
+    channel: eslint-5
   rubocop:
     enabled: true
     channel: rubocop-0-54
diff --git a/.env.nanobox b/.env.nanobox
index 8e0af6a8a8a136f7b2350b38a1ac722dfc372cce..b60b6ee689729902d408338e32b20224ad933a0b 100644
--- a/.env.nanobox
+++ b/.env.nanobox
@@ -136,8 +136,8 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
 # Defaults to 60 seconds. Set to 0 to disable
 # SWIFT_CACHE_TTL=
 
-# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
-# S3_CLOUDFRONT_HOST=
+# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare)
+# S3_ALIAS_HOST=
 
 # Streaming API integration
 # STREAMING_API_BASE_URL=
diff --git a/.env.production.sample b/.env.production.sample
index ebb0788781d59a7dc0705cbdf298359eee60e282..d1164efdc0cce0882d2ec0cf594c3e59921d065d 100644
--- a/.env.production.sample
+++ b/.env.production.sample
@@ -134,8 +134,8 @@ SMTP_FROM_ADDRESS=notifications@example.com
 # Defaults to 60 seconds. Set to 0 to disable
 # SWIFT_CACHE_TTL=
 
-# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
-# S3_CLOUDFRONT_HOST=
+# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare)
+# S3_ALIAS_HOST=
 
 # Streaming API integration
 # STREAMING_API_BASE_URL=
@@ -162,6 +162,7 @@ STREAMING_CLUSTER_NUM=1
 # LDAP_BIND_DN=
 # LDAP_PASSWORD=
 # LDAP_UID=cn
+# LDAP_SEARCH_FILTER="%{uid}=%{email}"
 
 # PAM authentication (optional)
 # PAM authentication uses for the email generation the "email" pam variable
diff --git a/.env.test b/.env.test
index 726351c5e357c2fcf78bdb14a3073c3bfa038080..fa4e1d91fa81987eb63a841a2e130db0186666a7 100644
--- a/.env.test
+++ b/.env.test
@@ -3,7 +3,3 @@ NODE_ENV=test
 # Federation
 LOCAL_DOMAIN=cb6e6126.ngrok.io
 LOCAL_HTTPS=true
-# test pam authentication
-PAM_ENABLED=true
-PAM_DEFAULT_SERVICE=pam_test
-PAM_CONTROLLED_SERVICE=pam_test_controlled
diff --git a/.env.vagrant b/.env.vagrant
index 04b889d0070e4ad8e01c23a2ca6f977f5a65b341..f3b54f6e38646e2515fe7f964fef9055b8d3d834 100644
--- a/.env.vagrant
+++ b/.env.vagrant
@@ -1,2 +1,2 @@
 VAGRANT=true
-LOCAL_DOMAIN=mastodon.dev
\ No newline at end of file
+LOCAL_DOMAIN=mastodon.local
diff --git a/.eslintignore b/.eslintignore
index 6d540c41387223b03972cebb21c4f2e2020c4541..d4930e1f5280020eb83d26c3d83cbcc4a35d26f5 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,30 +1,13 @@
-# See https://help.github.com/articles/ignoring-files for more about ignoring files.
-#
-# If you find yourself ignoring temporary files generated by your text editor
-# or operating system, you probably want to add a global ignore instead:
-#   git config --global core.excludesfile '~/.gitignore_global'
-
-# Ignore bundler config.
-/.bundle
-
-# Ignore the default SQLite database.
-/db/*.sqlite3
-/db/*.sqlite3-journal
-
-# Ignore all logfiles and tempfiles.
-/log/*
-!/log/.keep
-/tmp
-coverage
-public/system
-public/assets
-.env
-.env.production
-node_modules/
-neo4j/
-
-# Ignore Vagrant files
-.vagrant/
-
-# Ignore Capistrano customizations
-config/deploy/*
+/build/**
+/coverage/**
+/db/**
+/lib/**
+/log/**
+/node_modules/**
+/nonobox/**
+/public/**
+!/public/embed.js
+/spec/**
+/tmp/**
+/vendor/**
+!.eslintrc.js
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000000000000000000000000000000000000..56e3d0530f5918e63b5e00729d777401c603a2bb
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,199 @@
+module.exports = {
+  root: true,
+
+  env: {
+    browser: true,
+    node: true,
+    es6: true,
+    jest: true,
+  },
+
+  globals: {
+    ATTACHMENT_HOST: false,
+  },
+
+  parser: 'babel-eslint',
+
+  plugins: [
+    'react',
+    'jsx-a11y',
+    'import',
+    'promise',
+  ],
+
+  parserOptions: {
+    sourceType: 'module',
+    ecmaFeatures: {
+      experimentalObjectRestSpread: true,
+      jsx: true,
+    },
+    ecmaVersion: 2018,
+  },
+
+  settings: {
+    react: {
+      version: 'detect',
+    },
+    'import/extensions': [
+      '.js',
+    ],
+    'import/ignore': [
+      'node_modules',
+      '\\.(css|scss|json)$',
+    ],
+  },
+
+  rules: {
+    'brace-style': 'warn',
+    'comma-dangle': ['error', 'always-multiline'],
+    'comma-spacing': [
+      'warn',
+      {
+        before: false,
+        after: true,
+      },
+    ],
+    'comma-style': ['warn', 'last'],
+    'consistent-return': 'error',
+    'dot-notation': 'error',
+    eqeqeq: 'error',
+    indent: ['warn', 2],
+    'jsx-quotes': ['error', 'prefer-single'],
+    'no-catch-shadow': 'error',
+    'no-cond-assign': 'error',
+    'no-console': [
+      'warn',
+      {
+        allow: [
+          'error',
+          'warn',
+        ],
+      },
+    ],
+    'no-fallthrough': 'error',
+    'no-irregular-whitespace': 'error',
+    'no-mixed-spaces-and-tabs': 'warn',
+    'no-nested-ternary': 'warn',
+    'no-trailing-spaces': 'warn',
+    'no-undef': 'error',
+    'no-unreachable': 'error',
+    'no-unused-expressions': 'error',
+    'no-unused-vars': [
+      'error',
+      {
+        vars: 'all',
+        args: 'after-used',
+        ignoreRestSiblings: true,
+      },
+    ],
+    'object-curly-spacing': ['error', 'always'],
+    'padded-blocks': [
+      'error',
+      {
+        classes: 'always',
+      },
+    ],
+    quotes: ['error', 'single'],
+    semi: 'error',
+    strict: 'off',
+    'valid-typeof': 'error',
+
+    'react/jsx-boolean-value': 'error',
+    'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
+    'react/jsx-curly-spacing': 'error',
+    'react/jsx-equals-spacing': 'error',
+    'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
+    'react/jsx-indent': ['error', 2],
+    'react/jsx-no-bind': 'error',
+    'react/jsx-no-duplicate-props': 'error',
+    'react/jsx-no-undef': 'error',
+    'react/jsx-tag-spacing': 'error',
+    'react/jsx-uses-react': 'error',
+    'react/jsx-uses-vars': 'error',
+    'react/jsx-wrap-multilines': 'error',
+    'react/no-multi-comp': 'off',
+    'react/no-string-refs': 'error',
+    'react/prop-types': 'error',
+    'react/self-closing-comp': 'error',
+
+    'jsx-a11y/accessible-emoji': 'warn',
+    'jsx-a11y/alt-text': 'warn',
+    'jsx-a11y/anchor-has-content': 'warn',
+    'jsx-a11y/anchor-is-valid': [
+      'warn',
+      {
+        components: [
+          'Link',
+          'NavLink',
+        ],
+        specialLink: [
+          'to',
+        ],
+        aspect: [
+          'noHref',
+          'invalidHref',
+          'preferButton',
+        ],
+      },
+    ],
+    'jsx-a11y/aria-activedescendant-has-tabindex': 'warn',
+    'jsx-a11y/aria-props': 'warn',
+    'jsx-a11y/aria-proptypes': 'warn',
+    'jsx-a11y/aria-role': 'warn',
+    'jsx-a11y/aria-unsupported-elements': 'warn',
+    'jsx-a11y/heading-has-content': 'warn',
+    'jsx-a11y/html-has-lang': 'warn',
+    'jsx-a11y/iframe-has-title': 'warn',
+    'jsx-a11y/img-redundant-alt': 'warn',
+    'jsx-a11y/interactive-supports-focus': 'warn',
+    'jsx-a11y/label-has-for': 'off',
+    'jsx-a11y/mouse-events-have-key-events': 'warn',
+    'jsx-a11y/no-access-key': 'warn',
+    'jsx-a11y/no-distracting-elements': 'warn',
+    'jsx-a11y/no-noninteractive-element-interactions': [
+      'warn',
+      {
+        handlers: [
+          'onClick',
+        ],
+      },
+    ],
+    'jsx-a11y/no-onchange': 'warn',
+    'jsx-a11y/no-redundant-roles': 'warn',
+    'jsx-a11y/no-static-element-interactions': [
+      'warn',
+      {
+        handlers: [
+          'onClick',
+        ],
+      },
+    ],
+    'jsx-a11y/role-has-required-aria-props': 'warn',
+    'jsx-a11y/role-supports-aria-props': 'off',
+    'jsx-a11y/scope': 'warn',
+    'jsx-a11y/tabindex-no-positive': 'warn',
+
+    'import/extensions': [
+      'error',
+      'always',
+      {
+        js: 'never',
+      },
+    ],
+    'import/newline-after-import': 'error',
+    'import/no-extraneous-dependencies': [
+      'error',
+      {
+        devDependencies: [
+          'config/webpack/**',
+          'app/javascript/mastodon/test_setup.js',
+          'app/javascript/**/__tests__/**',
+        ],
+      },
+    ],
+    'import/no-unresolved': 'error',
+    'import/no-webpack-loader-syntax': 'error',
+
+    'promise/catch-or-return': 'error',
+  },
+};
diff --git a/.eslintrc.yml b/.eslintrc.yml
deleted file mode 100644
index fbda265498119748c8dac30462ebc47ab5caad24..0000000000000000000000000000000000000000
--- a/.eslintrc.yml
+++ /dev/null
@@ -1,170 +0,0 @@
----
-root: true
-
-env:
-  browser: true
-  node: true
-  es6: true
-  jest: true
-
-globals:
-  ATTACHMENT_HOST: false
-
-parser: babel-eslint
-
-plugins:
-- react
-- jsx-a11y
-- import
-- promise
-
-parserOptions:
-  sourceType: module
-  ecmaFeatures:
-    experimentalObjectRestSpread: true
-    jsx: true
-  ecmaVersion: 2018
-
-settings:
-  import/extensions:
-  - .js
-  import/ignore:
-  - node_modules
-  - \\.(css|scss|json)$
-
-rules:
-  brace-style: warn
-  comma-dangle:
-  - error
-  - always-multiline
-  comma-spacing:
-  - warn
-  - before: false
-    after: true
-  comma-style:
-  - warn
-  - last
-  consistent-return: error
-  dot-notation: error
-  eqeqeq: error
-  indent:
-  - warn
-  - 2
-  jsx-quotes:
-  - error
-  - prefer-single
-  no-catch-shadow: error
-  no-cond-assign: error
-  no-console:
-  - warn
-  - allow:
-    - error
-    - warn
-  no-fallthrough: error
-  no-irregular-whitespace: error
-  no-mixed-spaces-and-tabs: warn
-  no-nested-ternary: warn
-  no-trailing-spaces: warn
-  no-undef: error
-  no-unreachable: error
-  no-unused-expressions: error
-  no-unused-vars:
-  - error
-  - vars: all
-    args: after-used
-    ignoreRestSiblings: true
-  object-curly-spacing:
-  - error
-  - always
-  padded-blocks:
-  - error
-  - classes: always
-  quotes:
-  - error
-  - single
-  semi: error
-  strict: off
-  valid-typeof: error
-
-  react/jsx-boolean-value: error
-  react/jsx-closing-bracket-location:
-  - error
-  - line-aligned
-  react/jsx-curly-spacing: error
-  react/jsx-equals-spacing: error
-  react/jsx-first-prop-new-line:
-  - error
-  - multiline-multiprop
-  react/jsx-indent:
-  - error
-  - 2
-  react/jsx-no-bind: error
-  react/jsx-no-duplicate-props: error
-  react/jsx-no-undef: error
-  react/jsx-tag-spacing: error
-  react/jsx-uses-react: error
-  react/jsx-uses-vars: error
-  react/jsx-wrap-multilines: error
-  react/no-multi-comp: off
-  react/no-string-refs: error
-  react/prop-types: error
-  react/self-closing-comp: error
-
-  jsx-a11y/accessible-emoji: warn
-  jsx-a11y/alt-text: warn
-  jsx-a11y/anchor-has-content: warn
-  jsx-a11y/anchor-is-valid:
-  - warn
-  - components:
-    - Link
-    - NavLink
-    specialLink:
-    - to
-    aspect:
-    - noHref
-    - invalidHref
-    - preferButton
-  jsx-a11y/aria-activedescendant-has-tabindex: warn
-  jsx-a11y/aria-props: warn
-  jsx-a11y/aria-proptypes: warn
-  jsx-a11y/aria-role: warn
-  jsx-a11y/aria-unsupported-elements: warn
-  jsx-a11y/heading-has-content: warn
-  jsx-a11y/html-has-lang: warn
-  jsx-a11y/iframe-has-title: warn
-  jsx-a11y/img-redundant-alt: warn
-  jsx-a11y/interactive-supports-focus: warn
-  jsx-a11y/label-has-for: off
-  jsx-a11y/mouse-events-have-key-events: warn
-  jsx-a11y/no-access-key: warn
-  jsx-a11y/no-distracting-elements: warn
-  jsx-a11y/no-noninteractive-element-interactions:
-  - warn
-  - handlers:
-    - onClick
-  jsx-a11y/no-onchange: warn
-  jsx-a11y/no-redundant-roles: warn
-  jsx-a11y/no-static-element-interactions:
-  - warn
-  - handlers:
-    - onClick
-  jsx-a11y/role-has-required-aria-props: warn
-  jsx-a11y/role-supports-aria-props: off
-  jsx-a11y/scope: warn
-  jsx-a11y/tabindex-no-positive: warn
-
-  import/extensions:
-  - error
-  - always
-  - js: never
-  import/newline-after-import: error
-  import/no-extraneous-dependencies:
-  - error
-  - devDependencies:
-    - "config/webpack/**"
-    - "app/javascript/mastodon/test_setup.js"
-    - "app/javascript/**/__tests__/**"
-  import/no-unresolved: error
-  import/no-webpack-loader-syntax: error
-
-  promise/catch-or-return: error
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 602530db0e935b6915d2c3ff3ecfdd10d55ba690..f49964bd9f5bfb2637bd258c3c4b399020ad7600 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,12 +1,27 @@
 ---
 name: Bug Report
-about: Create a report to help us improve
+about: If something isn't working as expected
 
 ---
 
-[Issue text goes here].
+<!-- Make sure that you are submitting a new bug that was not previously reported or already fixed -->
 
-* * * *
+<!-- Please use a concise and distinct title for the issue -->
 
-- [ ] I searched or browsed the repo’s other issues to ensure this is not a duplicate.
-- [ ] This bug happens on a [tagged release](https://github.com/tootsuite/mastodon/releases) and not on `master` (If you're a user, don't worry about this).
+### Expected behaviour
+
+<!-- What should have happened? -->
+
+### Actual behaviour
+
+<!-- What happened? -->
+
+### Steps to reproduce the problem
+
+<!-- What were you trying to do? -->
+
+### Specifications
+
+<!-- What version or commit hash of Mastodon did you find this bug in? -->
+
+<!-- If a front-end issue, what browser and operating systems were you using? -->
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 46602fd2c0c9f57c2998c97190b33bd947431f3a..3890729e22f22d5933f2e852573d5ac6c0397fdb 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -1,11 +1,17 @@
 ---
 name: Feature Request
-about: Suggest an idea for this project
+about: I have a suggestion
 
 ---
 
-[Issue text goes here].
+<!-- Please use a concise and distinct title for the issue -->
 
-* * * *
+<!-- Consider: Could it be implemented as a 3rd party app using the REST API instead? -->
 
-- [ ] I searched or browsed the repo’s other issues to ensure this is not a duplicate.
+### Pitch
+
+<!-- Describe your idea for a feature. Make sure it has not already been suggested/implemented/turned down before -->
+
+### Motivation
+
+<!-- Why do you think this feature is needed? Who would benefit from it? -->
diff --git a/.github/ISSUE_TEMPLATE/support.md b/.github/ISSUE_TEMPLATE/support.md
new file mode 100644
index 0000000000000000000000000000000000000000..7fbc86ff14f699cf099f1d048bbc7ffa888337d8
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/support.md
@@ -0,0 +1,10 @@
+---
+name: Support
+about: Ask for help with your deployment
+
+---
+
+We primarily use GitHub as a bug and feature tracker. For usage questions, troubleshooting of deployments and other individual technical assistance, please use one of the resources below:
+
+- https://discourse.joinmastodon.org
+- #mastodon on irc.freenode.net
diff --git a/.nvmrc b/.nvmrc
index 1e8b314962144c26d5e0e50fd29d2ca327864913..45a4fb75db864000d01701c0f7a51864bd4daabf 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-6
+8
diff --git a/.postcssrc.yml b/.postcssrc.yml
deleted file mode 100644
index efffb39ba61f2ff62b95aa08c53cf7a39859e51c..0000000000000000000000000000000000000000
--- a/.postcssrc.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-plugins:
-  postcss-smart-import: {}
-  precss: {}
-  autoprefixer:
-    browsers:
-      - last 2 versions
-      - IE >= 11
-      - iOS >= 9
-  postcss-object-fit-images: {}
diff --git a/.rubocop.yml b/.rubocop.yml
index 6faeaca6f200fc371b27ae75f4b13f76db8a5762..59e8a757ac12ae9a2df6489e85a96cf2cbbf6d85 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -11,6 +11,7 @@ AllCops:
   - 'Vagrantfile'
   - 'vendor/**/*'
   - 'lib/json_ld/*'
+  - 'lib/templates/**/*'
 
 Bundler/OrderedGems:
   Enabled: false
@@ -61,6 +62,9 @@ Metrics/ParameterLists:
 Metrics/PerceivedComplexity:
   Max: 20
 
+Naming/MemoizedInstanceVariableName:
+  Enabled: false
+
 Rails:
   Enabled: true
 
@@ -70,6 +74,14 @@ Rails/HasAndBelongsToMany:
 Rails/SkipsModelValidations:
   Enabled: false
 
+Rails/HttpStatus:
+  Enabled: false
+
+Rails/Exit:
+  Exclude:
+    - 'lib/mastodon/*'
+    - 'lib/cli'
+
 Style/ClassAndModuleChildren:
   Enabled: false
 
diff --git a/.ruby-version b/.ruby-version
index 73462a5a13445f66009e00988279d30e55aa8363..e70b4523ae7ffe8aa3cac8ecd1b093fba5a98737 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.5.1
+2.6.0
diff --git a/AUTHORS.md b/AUTHORS.md
index c4bbb60140b17842aae4d2f60c3cddde91cec1da..1bcf455b11f1b10e450c6b760aa901d72a3c9a74 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -1,158 +1,199 @@
+Authors
+=======
+
 Mastodon is available on [GitHub](https://github.com/tootsuite/mastodon)
 and provided thanks to the work of the following contributors:
 
 * [Gargron](https://github.com/Gargron)
 * [ykzts](https://github.com/ykzts)
-* [mjankowski](https://github.com/mjankowski)
 * [akihikodaki](https://github.com/akihikodaki)
+* [ThibG](https://github.com/ThibG)
+* [mjankowski](https://github.com/mjankowski)
 * [unarist](https://github.com/unarist)
-* [yiskah](https://github.com/yiskah)
 * [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)
 * [abcang](https://github.com/abcang)
-* [ThibG](https://github.com/ThibG)
 * [lynlynlynx](https://github.com/lynlynlynx)
 * [alpaca-tc](https://github.com/alpaca-tc)
+* [mayaeh](https://github.com/mayaeh)
+* [renatolond](https://github.com/renatolond)
 * [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)
+* [mabkenar](https://github.com/mabkenar)
 * [nullkal](https://github.com/nullkal)
 * [yookoala](https://github.com/yookoala)
-* [ysksn](https://github.com/ysksn)
+* [Kjwon15](https://github.com/Kjwon15)
+* [shuheiktgw](https://github.com/shuheiktgw)
 * [ashfurrow](https://github.com/ashfurrow)
-* [eramdam](https://github.com/eramdam)
-* [mayaeh](https://github.com/mayaeh)
+* [Quenty31](https://github.com/Quenty31)
 * [zunda](https://github.com/zunda)
-* [ticky](https://github.com/ticky)
+* [eramdam](https://github.com/eramdam)
+* [takayamaki](https://github.com/takayamaki)
 * [masarakki](https://github.com/masarakki)
+* [ticky](https://github.com/ticky)
+* [danhunsaker](https://github.com/danhunsaker)
+* [ThisIsMissEm](https://github.com/ThisIsMissEm)
+* [hcmiya](https://github.com/hcmiya)
+* [stephenburgess8](https://github.com/stephenburgess8)
 * [Wonderfall](https://github.com/Wonderfall)
 * [matteoaquila](https://github.com/matteoaquila)
 * [rkarabut](https://github.com/rkarabut)
-* [stephenburgess8](https://github.com/stephenburgess8)
-* [Kjwon15](https://github.com/Kjwon15)
-* [Artoria2e5](https://github.com/Artoria2e5)
 * [yukimochi](https://github.com/yukimochi)
+* [Artoria2e5](https://github.com/Artoria2e5)
 * [marrus-sh](https://github.com/marrus-sh)
 * [krainboltgreene](https://github.com/krainboltgreene)
-* [renatolond](https://github.com/renatolond)
-* [BoFFire](https://github.com/BoFFire)
-* [clworld](https://github.com/clworld)
-* [danhunsaker](https://github.com/danhunsaker)
 * [patf](https://github.com/patf)
-* [Quenty31](https://github.com/Quenty31)
-* [MitarashiDango](https://github.com/MitarashiDango)
 * [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)
-* [takayamaki](https://github.com/takayamaki)
+* [MaciekBaron](https://github.com/MaciekBaron)
+* [MitarashiDango](mailto:mitarashidango@users.noreply.github.com)
+* [beatrix-bitrot](https://github.com/beatrix-bitrot)
 * [adbelle](https://github.com/adbelle)
 * [evanminto](https://github.com/evanminto)
-* [mabkenar](https://github.com/mabkenar)
 * [MightyPork](https://github.com/MightyPork)
-* [beatrix-bitrot](https://github.com/beatrix-bitrot)
 * [yhirano55](https://github.com/yhirano55)
 * [camponez](https://github.com/camponez)
+* [SerCom-KC](https://github.com/SerCom-KC)
 * [aschmitz](https://github.com/aschmitz)
+* [devkral](https://github.com/devkral)
 * [fpiesche](https://github.com/fpiesche)
 * [gandaro](https://github.com/gandaro)
 * [johnsudaar](https://github.com/johnsudaar)
 * [trebmuh](https://github.com/trebmuh)
-* [Sylvhem](https://github.com/Sylvhem)
+* [Rakib Hasan](mailto:rmhasan@gmail.com)
 * [lindwurm](https://github.com/lindwurm)
+* [victorhck](mailto:victorhck@geeko.site)
 * [voidsatisfaction](https://github.com/voidsatisfaction)
-* [neetshin](https://github.com/neetshin)
-* [valentin2105](https://github.com/valentin2105)
 * [hikari-no-yume](https://github.com/hikari-no-yume)
-* [Angristan](https://github.com/Angristan)
+* [angristan](https://github.com/angristan)
 * [seefood](https://github.com/seefood)
 * [jackjennings](https://github.com/jackjennings)
-* [hcmiya](https://github.com/hcmiya)
-* [nightpool](https://github.com/nightpool)
-* [salvadorpla](https://github.com/salvadorpla)
+* [spla](mailto:spla@mastodont.cat)
 * [expenses](https://github.com/expenses)
 * [walf443](https://github.com/walf443)
 * [JoelQ](https://github.com/JoelQ)
 * [mistydemeo](https://github.com/mistydemeo)
 * [dunn](https://github.com/dunn)
 * [xqus](https://github.com/xqus)
+* [hugogameiro](https://github.com/hugogameiro)
 * [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)
+* [fvh-P](https://github.com/fvh-P)
 * [contraexemplo](https://github.com/contraexemplo)
 * [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)
+* [valentin2105](https://github.com/valentin2105)
+* [yuntan](https://github.com/yuntan)
+* [goofy-bz](mailto:goofy@babelzilla.org)
 * [kadiix](https://github.com/kadiix)
 * [kodacs](https://github.com/kodacs)
-* [ProgVal](https://github.com/ProgVal)
+* [rtucker](https://github.com/rtucker)
+* [KScl](https://github.com/KScl)
 * [sterdev](https://github.com/sterdev)
 * [TheKinrar](https://github.com/TheKinrar)
 * [AA4ch1](https://github.com/AA4ch1)
 * [alexgleason](https://github.com/alexgleason)
 * [cpytel](https://github.com/cpytel)
 * [northerner](https://github.com/northerner)
-* [hnrysmth](https://github.com/hnrysmth)
-* [hugogameiro](https://github.com/hugogameiro)
+* [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)
 * [Naouak](https://github.com/Naouak)
-* [rtucker](https://github.com/rtucker)
+* [pawelngei](https://github.com/pawelngei)
 * [reneklacan](https://github.com/reneklacan)
-* [KScl](https://github.com/KScl)
-* [SerCom-KC](https://github.com/SerCom-KC)
+* [ekiru](https://github.com/ekiru)
 * [tcitworld](https://github.com/tcitworld)
 * [geta6](https://github.com/geta6)
-* [goofy-bz](https://github.com/goofy-bz)
 * [happycoloredbanana](https://github.com/happycoloredbanana)
 * [leopku](https://github.com/leopku)
 * [SansPseudoFix](https://github.com/SansPseudoFix)
 * [tomfhowe](https://github.com/tomfhowe)
 * [noraworld](https://github.com/noraworld)
-* [fvh-P](https://github.com/fvh-P)
+* [theboss](https://github.com/theboss)
 * [178inaba](https://github.com/178inaba)
-* [devkral](https://github.com/devkral)
+* [Aditoo17](https://github.com/Aditoo17)
 * [alyssais](https://github.com/alyssais)
 * [kodnaplakal](https://github.com/kodnaplakal)
 * [stalker314314](https://github.com/stalker314314)
 * [huertanix](https://github.com/huertanix)
 * [genesixx](https://github.com/genesixx)
-* [fhemberger](https://github.com/fhemberger)
 * [halkeye](https://github.com/halkeye)
 * [treby](https://github.com/treby)
-* [d6rkaiz](https://github.com/d6rkaiz)
 * [jpdevries](https://github.com/jpdevries)
-* [rndm-stranger](https://github.com/rndm-stranger)
+* [gdpelican](https://github.com/gdpelican)
+* [kmichl](https://github.com/kmichl)
+* [Kurtis Rainbolt-Greene](mailto:me@kurtisrainboltgreene.name)
 * [saper](https://github.com/saper)
 * [nevillepark](https://github.com/nevillepark)
 * [ornithocoder](https://github.com/ornithocoder)
 * [pierreozoux](https://github.com/pierreozoux)
-* [ramlmn](https://github.com/ramlmn)
+* [qguv](https://github.com/qguv)
+* [Ram Lmn](mailto:ramlmn@users.noreply.github.com)
 * [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)
-* [thor-the-norseman](https://github.com/thor-the-norseman)
+* [Thor Harald Johansen](mailto:thj@thj.no)
 * [0x70b1a5](https://github.com/0x70b1a5)
 * [gled-rs](https://github.com/gled-rs)
+* [Valentin_NC](mailto:valentin.ouvrard@nautile.sarl)
 * [R0ckweb](https://github.com/R0ckweb)
+* [caasi](https://github.com/caasi)
+* [chr-1x](https://github.com/chr-1x)
 * [esetomo](https://github.com/esetomo)
 * [foxiehkins](https://github.com/foxiehkins)
-* [sdukhovni](https://github.com/sdukhovni)
+* [hoodie](mailto:hoodiekitten@outlook.com)
+* [luzi82](https://github.com/luzi82)
+* [duxovni](https://github.com/duxovni)
+* [trwnh](https://github.com/trwnh)
 * [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)
+* [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)
@@ -164,37 +205,50 @@ and provided thanks to the work of the following contributors:
 * [cdutson](https://github.com/cdutson)
 * [farlistener](https://github.com/farlistener)
 * [DavidLibeau](https://github.com/DavidLibeau)
-* [SirCmpwn](https://github.com/SirCmpwn)
-* [MasterGroosha](https://github.com/MasterGroosha)
+* [ddevault](https://github.com/ddevault)
 * [Fjoerfoks](https://github.com/Fjoerfoks)
 * [fmauNeko](https://github.com/fmauNeko)
 * [gloaec](https://github.com/gloaec)
-* [greysteil](https://github.com/greysteil)
+* [Gomasy](https://github.com/Gomasy)
 * [unstabler](https://github.com/unstabler)
 * [potato4d](https://github.com/potato4d)
 * [h-izumi](https://github.com/h-izumi)
 * [ErikXXon](https://github.com/ErikXXon)
 * [ian-kelling](https://github.com/ian-kelling)
+* [immae](https://github.com/immae)
 * [foozmeat](https://github.com/foozmeat)
 * [jasonrhodes](https://github.com/jasonrhodes)
-* [asm](https://github.com/asm)
+* [Jason Snell](mailto:jason@newrelic.com)
 * [jviide](https://github.com/jviide)
+* [YuleZ](https://github.com/YuleZ)
 * [crakaC](https://github.com/crakaC)
 * [tkbky](https://github.com/tkbky)
+* [Kaylee](mailto:kaylee@codethat.sucks)
 * [Kazhnuz](https://github.com/Kazhnuz)
+* [connyduck](https://github.com/connyduck)
+* [Lindsey Bieda](mailto:lindseyb@users.noreply.github.com)
+* [Lorenz Diener](mailto:halcyon@icosahedron.website)
 * [alimony](https://github.com/alimony)
 * [mig5](https://github.com/mig5)
 * [ndarville](https://github.com/ndarville)
 * [Abzol](https://github.com/Abzol)
+* [pwoolcoc](https://github.com/pwoolcoc)
 * [xPaw](https://github.com/xPaw)
+* [petzah](https://github.com/petzah)
+* [ignisf](https://github.com/ignisf)
 * [raymestalez](https://github.com/raymestalez)
+* [remram44](https://github.com/remram44)
+* [sascha-sl](https://github.com/sascha-sl)
+* [u1-liquid](https://github.com/u1-liquid)
 * [sim6](https://github.com/sim6)
-* [ekiru](https://github.com/ekiru)
-* [Technowix](https://github.com/Technowix)
+* [stemid](https://github.com/stemid)
+* [sumdog](https://github.com/sumdog)
 * [ThomasLeister](https://github.com/ThomasLeister)
 * [mcat-ee](https://github.com/mcat-ee)
 * [tototoshi](https://github.com/tototoshi)
+* [TrashMacNugget](https://github.com/TrashMacNugget)
 * [VirtuBox](https://github.com/VirtuBox)
+* [Vladyslav](mailto:vaden@tuta.io)
 * [kaniini](https://github.com/kaniini)
 * [vayan](https://github.com/vayan)
 * [yannicka](https://github.com/yannicka)
@@ -202,45 +256,61 @@ and provided thanks to the work of the following contributors:
 * [zacanger](https://github.com/zacanger)
 * [amazedkoumei](https://github.com/amazedkoumei)
 * [anon5r](https://github.com/anon5r)
+* [aus-social](https://github.com/aus-social)
+* [imbsky](https://github.com/imbsky)
+* [bsky](mailto:me@imbsky.net)
 * [codl](https://github.com/codl)
+* [cpsdqs](https://github.com/cpsdqs)
 * [barzamin](https://github.com/barzamin)
 * [fhalna](https://github.com/fhalna)
 * [haoyayoi](https://github.com/haoyayoi)
 * [ik11235](https://github.com/ik11235)
 * [kawax](https://github.com/kawax)
 * [007lva](https://github.com/007lva)
+* [mbajur](https://github.com/mbajur)
 * [matsurai25](https://github.com/matsurai25)
 * [mecab](https://github.com/mecab)
 * [nicobz25](https://github.com/nicobz25)
 * [oliverkeeble](https://github.com/oliverkeeble)
 * [pinfort](https://github.com/pinfort)
 * [rbaumert](https://github.com/rbaumert)
+* [rhoio](https://github.com/rhoio)
 * [usagi-f](https://github.com/usagi-f)
 * [vidarlee](https://github.com/vidarlee)
 * [vjackson725](https://github.com/vjackson725)
 * [wxcafe](https://github.com/wxcafe)
-* [rinsuki](https://github.com/rinsuki)
+* [新都心(Neet Shin)](mailto:nucx@dio-vox.com)
 * [cygnan](https://github.com/cygnan)
 * [Awea](https://github.com/Awea)
 * [halcy](https://github.com/halcy)
-* [bounshi](https://github.com/bounshi)
+* [naaaaaaaaaaaf](https://github.com/naaaaaaaaaaaf)
 * [8398a7](https://github.com/8398a7)
 * [857b](https://github.com/857b)
+* [insom](https://github.com/insom)
+* [tachyons](https://github.com/tachyons)
+* [Esteth](https://github.com/Esteth)
 * [unascribed](https://github.com/unascribed)
 * [Aguay-val](https://github.com/Aguay-val)
+* [Akihiko Odaki](mailto:nekomanma@pixiv.co.jp)
 * [knu](https://github.com/knu)
+* [h3poteto](https://github.com/h3poteto)
+* [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)
+* [palindromordnilap](https://github.com/palindromordnilap)
 * [virtualpain](https://github.com/virtualpain)
 * [sapphirus](https://github.com/sapphirus)
 * [amandavisconti](https://github.com/amandavisconti)
 * [ameliavoncat](https://github.com/ameliavoncat)
 * [ilpianista](https://github.com/ilpianista)
-* [andydrop](https://github.com/andydrop)
+* [Andreas Drop](mailto:andy@remline.de)
+* [andi1984](https://github.com/andi1984)
 * [schas002](https://github.com/schas002)
+* [abackstrom](https://github.com/abackstrom)
 * [jumbosushi](https://github.com/jumbosushi)
 * [ayumin](https://github.com/ayumin)
 * [BaptisteGelez](https://github.com/BaptisteGelez)
@@ -251,6 +321,7 @@ and provided thanks to the work of the following contributors:
 * [brycied00d](https://github.com/brycied00d)
 * [carlosjs23](https://github.com/carlosjs23)
 * [cgxxx](https://github.com/cgxxx)
+* [kibitan](https://github.com/kibitan)
 * [chrisheninger](https://github.com/chrisheninger)
 * [chris-martin](https://github.com/chris-martin)
 * [DoubleMalt](https://github.com/DoubleMalt)
@@ -259,22 +330,34 @@ and provided thanks to the work of the following contributors:
 * [chriswk](https://github.com/chriswk)
 * [csu](https://github.com/csu)
 * [kklleemm](https://github.com/kklleemm)
-* [monsterpit-daggertooth](https://github.com/monsterpit-daggertooth)
+* [colindean](https://github.com/colindean)
+* [dachinat](https://github.com/dachinat)
+* [multiple-creatures](https://github.com/multiple-creatures)
 * [watilde](https://github.com/watilde)
 * [daprice](https://github.com/daprice)
 * [dar5hak](https://github.com/dar5hak)
 * [kant](https://github.com/kant)
+* [maxolasersquad](https://github.com/maxolasersquad)
 * [singingwolfboy](https://github.com/singingwolfboy)
 * [davidcelis](https://github.com/davidcelis)
+* [davefp](https://github.com/davefp)
 * [yipdw](https://github.com/yipdw)
 * [debanshuk](https://github.com/debanshuk)
+* [Derek Lewis](mailto:derekcecillewis@gmail.com)
 * [dblandin](https://github.com/dblandin)
-* [aranaur](https://github.com/aranaur)
+* [Drew Gates](mailto:aranaur@users.noreply.github.com)
+* [dtschust](https://github.com/dtschust)
+* [Dryusdan](https://github.com/Dryusdan)
+* [eai04191](https://github.com/eai04191)
 * [d3vgru](https://github.com/d3vgru)
 * [Elizafox](https://github.com/Elizafox)
 * [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)
+* [fwenzel](https://github.com/fwenzel)
+* [GenbuHase](https://github.com/GenbuHase)
 * [hattori6789](https://github.com/hattori6789)
 * [algernon](https://github.com/algernon)
 * [Fastbyte01](https://github.com/Fastbyte01)
@@ -283,22 +366,25 @@ and provided thanks to the work of the following contributors:
 * [Fiaxhs](https://github.com/Fiaxhs)
 * [reedcourty](https://github.com/reedcourty)
 * [anneau](https://github.com/anneau)
+* [lanodan](https://github.com/lanodan)
+* [Harmon758](https://github.com/Harmon758)
 * [HellPie](https://github.com/HellPie)
 * [Habu-Kagumba](https://github.com/Habu-Kagumba)
-* [hinaloe](https://github.com/hinaloe)
 * [suzukaze](https://github.com/suzukaze)
 * [Hiromi-Kai](https://github.com/Hiromi-Kai)
+* [hishamhm](https://github.com/hishamhm)
 * [musashino205](https://github.com/musashino205)
 * [iwaim](https://github.com/iwaim)
 * [valrus](https://github.com/valrus)
 * [IMcD23](https://github.com/IMcD23)
 * [yi0713](https://github.com/yi0713)
-* [immae](https://github.com/immae)
 * [iblech](https://github.com/iblech)
+* [usbsnowcrash](https://github.com/usbsnowcrash)
 * [jack-michaud](https://github.com/jack-michaud)
 * [Floppy](https://github.com/Floppy)
 * [loomchild](https://github.com/loomchild)
-* [docjkl](https://github.com/docjkl)
+* [jenkr55](https://github.com/jenkr55)
+* [press5](https://github.com/press5)
 * [TrollDecker](https://github.com/TrollDecker)
 * [jmontane](https://github.com/jmontane)
 * [jonathanklee](https://github.com/jonathanklee)
@@ -307,28 +393,33 @@ and provided thanks to the work of the following contributors:
 * [joshuap](https://github.com/joshuap)
 * [Tiwy57](https://github.com/Tiwy57)
 * [xuv](https://github.com/xuv)
-* [Jnsll](https://github.com/Jnsll)
+* [June Sallou](mailto:jnsll@users.noreply.github.com)
 * [j0k3r](https://github.com/j0k3r)
 * [KEINOS](https://github.com/KEINOS)
 * [futoase](https://github.com/futoase)
-* [abjectio](https://github.com/abjectio)
+* [Pneumaticat](https://github.com/Pneumaticat)
+* [Kit Redgrave](mailto:qwertyitis@gmail.com)
+* [Knut Erik](mailto:abjectio@users.noreply.github.com)
 * [mkody](https://github.com/mkody)
-* [connyduck](https://github.com/connyduck)
 * [k0ta0uchi](https://github.com/k0ta0uchi)
 * [KrzysiekJ](https://github.com/KrzysiekJ)
 * [leowzukw](https://github.com/leowzukw)
-* [lmorchard](https://github.com/lmorchard)
+* [Tak](https://github.com/Tak)
 * [cacheflow](https://github.com/cacheflow)
 * [ldidry](https://github.com/ldidry)
 * [jemus42](https://github.com/jemus42)
 * [lfuelling](https://github.com/lfuelling)
 * [Grabacr07](https://github.com/Grabacr07)
 * [mistermantas](https://github.com/mistermantas)
+* [mareklach](https://github.com/mareklach)
 * [wirehack7](https://github.com/wirehack7)
+* [martymcguire](https://github.com/martymcguire)
 * [marvinkopf](https://github.com/marvinkopf)
 * [otsune](https://github.com/otsune)
-* [m-blc](https://github.com/m-blc)
+* [Mathias B](mailto:10813340+mathias-b@users.noreply.github.com)
 * [matt-auckland](https://github.com/matt-auckland)
+* [webroo](https://github.com/webroo)
+* [matthiasbeyer](https://github.com/matthiasbeyer)
 * [mattjmattj](https://github.com/mattjmattj)
 * [mtparet](https://github.com/mtparet)
 * [maximeborges](https://github.com/maximeborges)
@@ -336,16 +427,21 @@ and provided thanks to the work of the following contributors:
 * [michaeljdeeb](https://github.com/michaeljdeeb)
 * [Themimitoof](https://github.com/Themimitoof)
 * [cyweo](https://github.com/cyweo)
-* [M1dgard](https://github.com/M1dgard)
+* [Midgard](mailto:m1dgard@users.noreply.github.com)
 * [mike-burns](https://github.com/mike-burns)
 * [verymilan](https://github.com/verymilan)
 * [milmazz](https://github.com/milmazz)
+* [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)
 * [Nanamachi](https://github.com/Nanamachi)
+* [orinthe](https://github.com/orinthe)
+* [NecroTechno](https://github.com/NecroTechno)
+* [Dar13](https://github.com/Dar13)
 * [ngerakines](https://github.com/ngerakines)
 * [vonneudeck](https://github.com/vonneudeck)
 * [Ninetailed](https://github.com/Ninetailed)
@@ -355,96 +451,381 @@ and provided thanks to the work of the following contributors:
 * [norayr](https://github.com/norayr)
 * [joyeusenoelle](https://github.com/joyeusenoelle)
 * [OlivierNicole](https://github.com/OlivierNicole)
+* [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)
-* [pwoolcoc](https://github.com/pwoolcoc)
 * [peterkeen](https://github.com/peterkeen)
-* [petzah](https://github.com/petzah)
-* [ignisf](https://github.com/ignisf)
+* [pgate](https://github.com/pgate)
+* [retokromer](https://github.com/retokromer)
 * [rfwatson](https://github.com/rfwatson)
 * [rfreebern](https://github.com/rfreebern)
+* [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)
-* [larkinscott](https://github.com/larkinscott)
-* [imolein](https://github.com/imolein)
-* [blinry](https://github.com/blinry)
-* [Noiwex](https://github.com/Noiwex)
-* [yuki764](https://github.com/yuki764)
-* [shnjp](https://github.com/shnjp)
-* [ernix](https://github.com/ernix)
-* [rosylilly](https://github.com/rosylilly)
-* [shouko](https://github.com/shouko)
-* [sossii](https://github.com/sossii)
-* [StefOfficiel](https://github.com/StefOfficiel)
-* [svetlik](https://github.com/svetlik)
-* [dereckson](https://github.com/dereckson)
-* [theboss](https://github.com/theboss)
-* [takp](https://github.com/takp)
-* [tkusano](https://github.com/tkusano)
-* [TheInventrix](https://github.com/TheInventrix)
-* [shug0](https://github.com/shug0)
-* [Fortyseven](https://github.com/Fortyseven)
-* [tobypinder](https://github.com/tobypinder)
-* [tomosm](https://github.com/tomosm)
-* [TomoyaShibata](https://github.com/TomoyaShibata)
-* [TrashMacNugget](https://github.com/TrashMacNugget)
-* [treyssatvincent](https://github.com/treyssatvincent)
-* [optikfluffel](https://github.com/optikfluffel)
-* [vmincev](https://github.com/vmincev)
-* [waldyrious](https://github.com/waldyrious)
-* [tahnok](https://github.com/tahnok)
-* [YDrogen](https://github.com/YDrogen)
-* [YOSHIOKAEiichiro](https://github.com/YOSHIOKAEiichiro)
-* [S-YOU](https://github.com/S-YOU)
-* [YaQ00](https://github.com/YaQ00)
-* [yanakend](https://github.com/yanakend)
-* [orzFly](https://github.com/orzFly)
-* [chansuke](https://github.com/chansuke)
-* [yuntan](https://github.com/yuntan)
-* [LogicalDash](https://github.com/LogicalDash)
-* [ZiiX](https://github.com/ZiiX)
-* [benklop](https://github.com/benklop)
-* [caasi](https://github.com/caasi)
-* [caesarologia](https://github.com/caesarologia)
-* [chrolis](https://github.com/chrolis)
-* [cormojs](https://github.com/cormojs)
-* [cpsdqs](https://github.com/cpsdqs)
-* [d0p1s4m4](https://github.com/d0p1s4m4)
-* [evilny0](https://github.com/evilny0)
-* [febrezo](https://github.com/febrezo)
-* [fsubal](https://github.com/fsubal)
-* [dikky1218](https://github.com/dikky1218)
-* [gentarok](https://github.com/gentarok)
-* [hakoai](https://github.com/hakoai)
-* [chaosbunker](https://github.com/chaosbunker)
-* [isati](https://github.com/isati)
-* [jkap](https://github.com/jkap)
-* [jirayudech](https://github.com/jirayudech)
-* [jukper](https://github.com/jukper)
-* [karlyeurl](https://github.com/karlyeurl)
-* [kedamaDQ](https://github.com/kedamaDQ)
-* [kuro5hin](https://github.com/kuro5hin)
-* [maxypy](https://github.com/maxypy)
-* [marcus-herrmann](https://github.com/marcus-herrmann)
-* [mshrtkch](https://github.com/mshrtkch)
-* [muan](https://github.com/muan)
-* [rch850](https://github.com/rch850)
-* [roikale](https://github.com/roikale)
-* [rysiekpl](https://github.com/rysiekpl)
-* [saturday06](https://github.com/saturday06)
-* [scriptjunkie](https://github.com/scriptjunkie)
-* [seekr](https://github.com/seekr)
-* [syui](https://github.com/syui)
-* [tackeyy](https://github.com/tackeyy)
-* [tmyt](https://github.com/tmyt)
-* [utam0k](https://github.com/utam0k)
-* [vpzomtrrfrt](https://github.com/vpzomtrrfrt)
-* [walfie](https://github.com/walfie)
-* [y-temp4](https://github.com/y-temp4)
-* [ymmtmdk](https://github.com/ymmtmdk)
+* [Scott Larkin](mailto:scott@codeclimate.com)
+* [Sebastian Hübner](mailto:imolein@users.noreply.github.com)
+* [Sebastian Morr](mailto:sebastian@morr.cc)
+* [Sergei Č](mailto:noiwex1911@gmail.com)
+* [Setuu](mailto:yuki764setuu@gmail.com)
+* [Shaun Gillies](mailto:me@shaungillies.net)
+* [Shin Adachi](mailto:shn@glucose.jp)
+* [Shin Kojima](mailto:shin@kojima.org)
+* [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)
+* [StefOfficiel](mailto:pichard.stephane@free.fr)
+* [Steven Tappert](mailto:admin@dark-it.net)
+* [Svetlozar Todorov](mailto:svetlik@users.noreply.github.com)
+* [Sébastien Santoro](mailto:dereckson@espace-win.org)
+* [Tad Thorley](mailto:phaedryx@users.noreply.github.com)
+* [Takayoshi Nishida](mailto:takayoshi.nishida@gmail.com)
+* [Takayuki KUSANO](mailto:github@tkusano.jp)
+* [TakesxiSximada](mailto:takesxi.sximada@gmail.com)
+* [TheInventrix](mailto:theinventrix@users.noreply.github.com)
+* [Thomas Alberola](mailto:thomas@needacoffee.fr)
+* [Toby Deshane](mailto:fortyseven@users.noreply.github.com)
+* [Toby Pinder](mailto:gigitrix@gmail.com)
+* [Tomonori Murakami](mailto:crosslife777@gmail.com)
+* [TomoyaShibata](mailto:wind.of.hometown@gmail.com)
+* [Treyssat-Vincent Nino](mailto:treyssatvincent@users.noreply.github.com)
+* [Udo Kramer](mailto:optik@fluffel.io)
+* [Una](mailto:una@unascribed.com)
+* [Ushitora Anqou](mailto:ushitora_anqou@yahoo.co.jp)
+* [Valentin Lorentz](mailto:progval+git@progval.net)
+* [Vladimir Mincev](mailto:vladimir@canicinteractive.com)
+* [Waldir Pimenta](mailto:waldyrious@gmail.com)
+* [Wesley Ellis](mailto:tahnok@gmail.com)
+* [Wiktor](mailto:wiktor@metacode.biz)
+* [Wonderfall](mailto:wonderfall@schrodinger.io)
+* [YDrogen](mailto:ydrogen45@gmail.com)
+* [YMHuang](mailto:ymhuang@fmbase.tw)
+* [YOSHIOKA Eiichiro](mailto:yoshioka.eiichiro@gmail.com)
+* [YOU](mailto:stackexchange.you@gmail.com)
+* [YaQ](mailto:i_k_o_m_a_7@yahoo.co.jp)
+* [Yanaken](mailto:yanakend@gmail.com)
+* [Yann Klis](mailto:yann.klis@gmail.com)
+* [Yeechan Lu](mailto:wz.bluesnow@gmail.com)
+* [Yusuke Abe](mailto:moonset20@gmail.com)
+* [Zachary Spector](mailto:logicaldash@gmail.com)
+* [ZiiX](mailto:ziix@users.noreply.github.com)
+* [asria-jp](mailto:is@alicematic.com)
+* [ava](mailto:vladooku@users.noreply.github.com)
+* [benklop](mailto:benklop@gmail.com)
+* [bsky](mailto:git@imbsky.net)
+* [caesarologia](mailto:lopesgemelli.1@gmail.com)
+* [cbayerlein](mailto:c.bayerlein@gmail.com)
+* [chrolis](mailto:chrolis@users.noreply.github.com)
+* [cormo](mailto:cormorant2+github@gmail.com)
+* [d0p1](mailto:dopi-sama@hush.com)
+* [evilny0](mailto:evilny0@moomoocamp.net)
+* [febrezo](mailto:felixbrezo@gmail.com)
+* [fsubal](mailto:fsubal@users.noreply.github.com)
+* [fusshi-](mailto:dikky1218@users.noreply.github.com)
+* [gentaro](mailto:gentaroooo@gmail.com)
+* [hakoai](mailto:hk--76@qa2.so-net.ne.jp)
+* [haosbvnker](mailto:github@chaosbunker.com)
+* [isati](mailto:phil@juchnowi.cz)
+* [jacob](mailto:jacobherringtondeveloper@gmail.com)
+* [jenn kaplan](mailto:me@jkap.io)
+* [jirayudech](mailto:jirayudech@gmail.com)
+* [jomo](mailto:github@jomo.tv)
+* [jooops](mailto:joops@autistici.org)
+* [jukper](mailto:jukkaperanto@gmail.com)
+* [jumoru](mailto:jumoru@mailbox.org)
+* [karlyeurl](mailto:karl.yeurl@gmail.com)
+* [kedama](mailto:32974885+kedamadq@users.noreply.github.com)
+* [kodai](mailto:shirafuta.kodai@gmail.com)
+* [kuro5hin](mailto:rusty@kuro5hin.org)
+* [luzpaz](mailto:luzpaz@users.noreply.github.com)
+* [maxypy](mailto:maxime@mpigou.fr)
+* [mhe](mailto:mail@marcus-herrmann.com)
+* [mimikun](mailto:dzdzble_effort_311@outlook.jp)
+* [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)
+* [saturday06](mailto:dyob@lunaport.net)
+* [scriptjunkie](mailto:scriptjunkie@scriptjunkie.us)
+* [seekr](mailto:mario.drs@gmail.com)
+* [sundevour](mailto:31990469+sundevour@users.noreply.github.com)
+* [syui](mailto:syui@users.noreply.github.com)
+* [tackeyy](mailto:mailto.takita.yusuke@gmail.com)
+* [tateisu](mailto:tateisu@gmail.com)
+* [tmyt](mailto:shigure@refy.net)
+* [trevDev()](mailto:trev@trevdev.ca)
+* [utam0k](mailto:k0ma@utam0k.jp)
+* [vpzomtrrfrt](mailto:vpzomtrrfrt@gmail.com)
+* [walfie](mailto:walfington@gmail.com)
+* [y-temp4](mailto:y.temp4@gmail.com)
+* [ymmtmdk](mailto:ymmtmdk@gmail.com)
+* [yoshipc](mailto:yoooo@yoshipc.net)
+* [Özcan Zafer AYAN](mailto:ozcanzaferayan@gmail.com)
+* [ばん](mailto:detteiu0321@gmail.com)
+* [みたらしだんご](mailto:mitarashidango@users.noreply.github.com)
+* [りんすき](mailto:6533808+rinsuki@users.noreply.github.com)
+* [ヨイツの賢狼ホロ | 3rd style](mailto:horo@yoitsu.moe)
+* [猫吸血鬼ディフリス / 猫ロキP](mailto:deflis@gmail.com)
+* [艮 鮟鱇](mailto:ushitora_anqou@yahoo.co.jp)
+* [西小倉宏信](mailto:nishiko@mindia.jp)
+* [雨宮美羽](mailto:k737566@gmail.com)
 
 This document is provided for informational purposes only. Since it is only updated once per release, the version you are looking at may be currently out of date. To see the full list of contributors, consider looking at the [git history](https://github.com/tootsuite/mastodon/graphs/contributors) instead.
+
+## Translators
+
+Following people have contributed to translation of Mastodon:
+
+- **Arabic**
+  - ButterflyOfFire
+- **Asturian**
+  - ButterflyOfFire
+  - Enol P.
+- **Basque**
+  - Aitzol
+  - ButterflyOfFire
+  - Gorka Azkarate
+  - Osoitz
+  - Peru Iparragirre
+- **Bulgarian**
+  - ButterflyOfFire
+- **Catalan**
+  - ButterflyOfFire
+  - Joan Montané
+  - Jose Luis
+  - spla
+- **Chinese (Hong Kong)**
+  - ButterflyOfFire
+  - Luzi Leung
+- **Chinese (Simplified)**
+  - Allen Zhong
+  - ButterflyOfFire
+  - SerCom_KC
+- **Chinese (Traditional)**
+  - ButterflyOfFire
+  - James58899
+  - Jeff Huang
+  - S1ttidoe477
+  - SHA265
+- **Corsican**
+  - Alix D. R.
+  - ButterflyOfFire
+- **Croatian**
+  - ButterflyOfFire
+- **Czech**
+  - ButterflyOfFire
+  - Lorem Ipsum
+  - Marek Ľach
+- **Danish**
+  - ButterflyOfFire
+  - Rasmus Sæderup
+- **Dutch**
+  - ButterflyOfFire
+  - Jelv
+  - jeroenpraat
+  - rscmbbng
+- **English**
+  - ButterflyOfFire
+  - Renato "Lond" Cerqueira
+- **Esperanto**
+  - ButterflyOfFire
+  - Jeong Arm
+  - Martin Bodin
+  - Mélanie Chauvel
+  - Vanege
+  - tuxayo/Victor Grousset
+- **Finnish**
+  - ButterflyOfFire
+  - Jonne Arjoranta
+  - S Heija
+  - Taru Luojola
+- **French**
+  - Alda Marteau-Hardi
+  - Alix D. R.
+  - Baptiste Jonglez
+  - ButterflyOfFire
+  - Franck Paul
+  - Jean-Baptiste Holcroft
+  - Jonathan Chan
+  - Letiteuf55
+  - Martin Bodin
+  - Mélanie Chauvel
+  - Olivier Humbert
+  - Paul Marques Mota
+  - Sylvhem
+  - Technowix
+  - Thibaut Girka
+  - Théodore
+  - azenet
+  - codl
+- **Galician**
+  - ButterflyOfFire
+  - Xose M.
+  - manequim
+- **Georgian**
+  - ButterflyOfFire
+- **German**
+  - Benedikt Geißler
+  - ButterflyOfFire
+  - Daniel
+  - Eugen Rochko
+  - Koyu Berteon
+  - Patrick Figel
+  - Weblate Admin
+  - averageunicorn
+  - ePirat
+  - koyu
+  - larsreineke
+  - lilo
+- **Greek**
+  - Antonis
+  - ButterflyOfFire
+  - Dimitris Maroulidis
+  - Konstantinos Grevenitis
+- **Hebrew**
+  - ButterflyOfFire
+  - Ira
+  - Yaron Shahrabani
+- **Hungarian**
+  - Adam Paszternak
+  - ButterflyOfFire
+  - Tibike Miklós
+- **Ido**
+  - ButterflyOfFire
+- **Indonesian**
+  - Alfiana Sibuea
+  - ButterflyOfFire
+  - Dito Kurnia Pratama
+  - Eirworks
+  - afachri
+  - se7entime
+- **Italian**
+  - Alessandro Levati
+  - ButterflyOfFire
+  - Giuseppe Pignataro
+  - Stefano
+- **Japanese**
+  - ButterflyOfFire
+  - Kumasun Morino
+  - Yamagishi Kazutoshi
+  - mayaeh
+  - osapon
+  - unarist
+  - 小鳥遊まりあ
+  - 森の子リスのミーコの大冒険
+- **Korean**
+  - ButterflyOfFire
+  - Jeong Arm
+  - Minori Hiraoka
+  - Yamagishi Kazutoshi
+- **Malay**
+  - ButterflyOfFire
+  - Muhammad Nur Hidayat (MNH48)
+- **Norwegian (old code)**
+  - ButterflyOfFire
+  - Espen Rønnevik
+  - Tale
+- **Occitan**
+  - ButterflyOfFire
+  - Maxenç
+  - Quenti2
+  - Quentí
+- **Persian**
+  - ButterflyOfFire
+  - Masoud Abkenar
+- **Polish**
+  - ButterflyOfFire
+  - Jakub Mendyk
+  - Marcin Mikołajczak
+  - Marek Ľach
+  - Stasiek Michalski
+  - krkk
+- **Portuguese**
+  - ButterflyOfFire
+  - Hugo Gameiro
+  - manequim
+- **Portuguese (Brazil)**
+  - André Andrade
+  - Anna e só
+  - ButterflyOfFire
+  - Renato "Lond" Cerqueira
+- **Romanian**
+  - ButterflyOfFire
+  - adrianbblk
+- **Russian**
+  - Andrew Zyabin
+  - ButterflyOfFire
+  - Evgeny Petrov
+  - Yaron Shahrabani
+- **Serbian**
+  - Branko Kokanovic
+  - Burekz Finezt
+  - ButterflyOfFire
+- **Serbian (latin)**
+  - ButterflyOfFire
+- **Slovak**
+  - ButterflyOfFire
+  - Ivan Pleva
+  - Lorem Ipsum
+  - Marek Ľach
+  - Peter
+- **Slovenian**
+  - ButterflyOfFire
+  - Kristijan Tkalec
+- **Spanish**
+  - Angeles Broullón
+  - Antón López
+  - ButterflyOfFire
+  - Carlos Mondragon
+  - David Charte
+  - Emmanuel
+  - Lothar Wolf
+  - Pablo de la Concepción Sanz
+- **Swedish**
+  - ButterflyOfFire
+  - Elias MÃ¥rtenson
+  - Isak Holmström
+  - Shellkr
+  - Stefan Midjich
+  - Tim Stahel
+- **Telugu**
+  - ButterflyOfFire
+  - Joseph Nuthalapati
+  - Ranjith Tellakula
+  - avndp
+- **Thai**
+  - ButterflyOfFire
+- **Turkish**
+  - ButterflyOfFire
+- **Ukrainian**
+  - ButterflyOfFire
+  - Ivan Verchenko
+  - alexcleac
+- **Welsh**
+  - ButterflyOfFire
+  - Jaz-Michael King
+  - Kevin Beynon
+  - Owain Rhys Lewis
+  - Renato "Lond" Cerqueira
+  - Rhoslyn Prys
+  - carl morris
+- **Armenian**
+  - ButterflyOfFire
+- **Latvian**
+  - ButterflyOfFire
+- **Tamil**
+  - ButterflyOfFire
+  - Prasanna Venkadesh
diff --git a/Aptfile b/Aptfile
index 5dac836079eb024570a7cf20847cd921bf9cbb13..0a01fa24bdf07b4f073b65fb5c95044bdd7e1181 100644
--- a/Aptfile
+++ b/Aptfile
@@ -5,6 +5,25 @@ libidn11
 libidn11-dev
 libpq-dev
 libprotobuf-dev
+libssl-dev
 libxdamage1
 libxfixes3
 protobuf-compiler
+zlib1g-dev
+libcairo2
+libcroco3
+libdatrie1
+libgdk-pixbuf2.0-0
+libgraphite2-3
+libharfbuzz0b
+libpango-1.0-0
+libpangocairo-1.0-0
+libpangoft2-1.0-0
+libpixman-1-0
+librsvg2-2
+libthai-data
+libthai0
+libvpx5
+libxcb-render0
+libxcb-shm0
+libxrender1
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..3bafbe1e9e11142715c94bd34cf1f9a4fcbca675
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,330 @@
+Changelog
+=========
+
+All notable changes to this project will be documented in this file.
+
+## [2.7.0] - 2019-01-20
+### Added
+
+- Add link for adding a user to a list from their profile ([namelessGonbai](https://github.com/tootsuite/mastodon/pull/9062))
+- Add joining several hashtags in a single column ([gdpelican](https://github.com/tootsuite/mastodon/pull/8904))
+- Add volume sliders for videos ([sumdog](https://github.com/tootsuite/mastodon/pull/9366))
+- Add a tooltip explaining what a locked account is ([pawelngei](https://github.com/tootsuite/mastodon/pull/9403))
+- Add preloaded cache for common JSON-LD contexts ([ThibG](https://github.com/tootsuite/mastodon/pull/9412))
+- Add profile directory ([Gargron](https://github.com/tootsuite/mastodon/pull/9427))
+- Add setting to not group reblogs in home feed ([ThibG](https://github.com/tootsuite/mastodon/pull/9248))
+- Add admin ability to remove a user's header image ([ThibG](https://github.com/tootsuite/mastodon/pull/9495))
+- Add account hashtags to ActivityPub actor JSON ([Gargron](https://github.com/tootsuite/mastodon/pull/9450))
+- Add error message for avatar image that's too large ([sumdog](https://github.com/tootsuite/mastodon/pull/9518))
+- Add notification quick-filter bar ([pawelngei](https://github.com/tootsuite/mastodon/pull/9399))
+- Add new first-time tutorial ([Gargron](https://github.com/tootsuite/mastodon/pull/9531))
+- Add moderation warnings ([Gargron](https://github.com/tootsuite/mastodon/pull/9519))
+- Add emoji codepoint mappings for v11.0 ([Gargron](https://github.com/tootsuite/mastodon/pull/9618))
+- Add REST API for creating an account ([Gargron](https://github.com/tootsuite/mastodon/pull/9572))
+- Add support for Malayalam in language filter ([tachyons](https://github.com/tootsuite/mastodon/pull/9624))
+- Add exclude_reblogs option to account statuses API ([Gargron](https://github.com/tootsuite/mastodon/pull/9640))
+- Add local followers page to admin account UI ([chr-1x](https://github.com/tootsuite/mastodon/pull/9610))
+- Add healthcheck commands to docker-compose.yml ([BenLubar](https://github.com/tootsuite/mastodon/pull/9143))
+- Add handler for Move activity to migrate followers ([Gargron](https://github.com/tootsuite/mastodon/pull/9629))
+- Add CSV export for lists and domain blocks ([Gargron](https://github.com/tootsuite/mastodon/pull/9677))
+- Add `tootctl accounts follow ACCT` ([Gargron](https://github.com/tootsuite/mastodon/pull/9414))
+- Add scheduled statuses ([Gargron](https://github.com/tootsuite/mastodon/pull/9706))
+- Add immutable caching for S3 objects ([nolanlawson](https://github.com/tootsuite/mastodon/pull/9722))
+- Add cache to custom emojis API ([Gargron](https://github.com/tootsuite/mastodon/pull/9732))
+- Add preview cards to non-detailed statuses on public pages ([Gargron](https://github.com/tootsuite/mastodon/pull/9714))
+- Add `mod` and `moderator` to list of default reserved usernames ([Gargron](https://github.com/tootsuite/mastodon/pull/9713))
+- Add quick links to the admin interface in the web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/8545))
+- Add `tootctl domains crawl` ([Gargron](https://github.com/tootsuite/mastodon/pull/9809))
+- Add attachment list fallback to public pages ([ThibG](https://github.com/tootsuite/mastodon/pull/9780))
+- Add `tootctl --version` ([Gargron](https://github.com/tootsuite/mastodon/pull/9835))
+- Add information about how to opt-in to the directory on the directory ([Gargron](https://github.com/tootsuite/mastodon/pull/9834))
+- Add timeouts for S3 ([Gargron](https://github.com/tootsuite/mastodon/pull/9842))
+- Add support for non-public reblogs from ActivityPub ([Gargron](https://github.com/tootsuite/mastodon/pull/9841))
+- Add sending of `Reject` activity when sending a `Block` activity ([ThibG](https://github.com/tootsuite/mastodon/pull/9811))
+
+### Changed
+
+- Temporarily pause timeline if mouse moved recently ([lmorchard](https://github.com/tootsuite/mastodon/pull/9200))
+- Change the password form order ([mayaeh](https://github.com/tootsuite/mastodon/pull/9267))
+- Redesign admin UI for accounts ([Gargron](https://github.com/tootsuite/mastodon/pull/9340), [Gargron](https://github.com/tootsuite/mastodon/pull/9643))
+- Redesign admin UI for instances/domain blocks ([Gargron](https://github.com/tootsuite/mastodon/pull/9645))
+- Swap avatar and header input fields in profile page ([ThibG](https://github.com/tootsuite/mastodon/pull/9271))
+- When posting in mobile mode, go back to previous history location ([ThibG](https://github.com/tootsuite/mastodon/pull/9502))
+- Split out is_changing_upload from is_submitting ([ThibG](https://github.com/tootsuite/mastodon/pull/9536))
+- Back to the getting-started when pins the timeline. ([kedamaDQ](https://github.com/tootsuite/mastodon/pull/9561))
+- Allow unauthenticated REST API access to GET /api/v1/accounts/:id/statuses ([Gargron](https://github.com/tootsuite/mastodon/pull/9573))
+- Limit maximum visibility of local silenced users to unlisted ([ThibG](https://github.com/tootsuite/mastodon/pull/9583))
+- Change API error message for unconfirmed accounts ([noellabo](https://github.com/tootsuite/mastodon/pull/9625))
+- Change the icon to "reply-all" when it's a reply to other accounts ([mayaeh](https://github.com/tootsuite/mastodon/pull/9378))
+- Do not ignore federated reports targetting already-reported accounts ([ThibG](https://github.com/tootsuite/mastodon/pull/9534))
+- Upgrade default Ruby version to 2.6.0 ([Gargron](https://github.com/tootsuite/mastodon/pull/9688))
+- Change e-mail digest frequency ([Gargron](https://github.com/tootsuite/mastodon/pull/9689))
+- Change Docker images for Tor support in docker-compose.yml ([Sir-Boops](https://github.com/tootsuite/mastodon/pull/9438))
+- Display fallback link card thumbnail when none is given ([Gargron](https://github.com/tootsuite/mastodon/pull/9715))
+- Change account bio length validation to ignore mention domains and URLs ([Gargron](https://github.com/tootsuite/mastodon/pull/9717))
+- Use configured contact user for "anonymous" federation activities ([yukimochi](https://github.com/tootsuite/mastodon/pull/9661))
+- Change remote interaction dialog to use specific actions instead of generic "interact" ([Gargron](https://github.com/tootsuite/mastodon/pull/9743))
+- Always re-fetch public key when signature verification fails to support blind key rotation ([ThibG](https://github.com/tootsuite/mastodon/pull/9667))
+- Make replies to boosts impossible, connect reply to original status instead ([valerauko](https://github.com/tootsuite/mastodon/pull/9129))
+- Change e-mail MX validation to check both A and MX records against blacklist ([Gargron](https://github.com/tootsuite/mastodon/pull/9489))
+- Hide floating action button on search and getting started pages ([tmm576](https://github.com/tootsuite/mastodon/pull/9826))
+- Redesign public hashtag page to use a masonry layout ([Gargron](https://github.com/tootsuite/mastodon/pull/9822))
+- Use `summary` as summary instead of content warning for converted ActivityPub objects ([Gargron](https://github.com/tootsuite/mastodon/pull/9823))
+- Display a double reply arrow on public pages for toots that are replies ([ThibG](https://github.com/tootsuite/mastodon/pull/9808))
+- Change admin UI right panel size to be wider ([Kjwon15](https://github.com/tootsuite/mastodon/pull/9768))
+
+### Removed
+
+- Remove links to bridge.joinmastodon.org (non-functional) ([Gargron](https://github.com/tootsuite/mastodon/pull/9608))
+- Remove LD-Signatures from activities that do not need them ([ThibG](https://github.com/tootsuite/mastodon/pull/9659))
+
+### Fixed
+
+- Remove unused computation of reblog references from updateTimeline ([ThibG](https://github.com/tootsuite/mastodon/pull/9244))
+- Fix loaded embeds resetting if a status arrives from API again ([ThibG](https://github.com/tootsuite/mastodon/pull/9270))
+- Fix race condition causing shallow status with only a "favourited" attribute ([ThibG](https://github.com/tootsuite/mastodon/pull/9272))
+- Remove intermediary arrays when creating hash maps from results ([Gargron](https://github.com/tootsuite/mastodon/pull/9291))
+- Extract counters from accounts table to account_stats table to improve performance ([Gargron](https://github.com/tootsuite/mastodon/pull/9295))
+- Change identities id column to a bigint ([Gargron](https://github.com/tootsuite/mastodon/pull/9371))
+- Fix conversations API pagination ([ThibG](https://github.com/tootsuite/mastodon/pull/9407))
+- Improve account suspension speed and completeness ([Gargron](https://github.com/tootsuite/mastodon/pull/9290))
+- Fix thread depth computation in statuses_controller ([ThibG](https://github.com/tootsuite/mastodon/pull/9426))
+- Fix database deadlocks by moving account stats update outside transaction ([ThibG](https://github.com/tootsuite/mastodon/pull/9437))
+- Escape HTML in profile name preview in profile settings ([pawelngei](https://github.com/tootsuite/mastodon/pull/9446))
+- Use same CORS policy for /@:username and /users/:username ([ThibG](https://github.com/tootsuite/mastodon/pull/9485))
+- Make custom emoji domains case insensitive ([Esteth](https://github.com/tootsuite/mastodon/pull/9474))
+- Various fixes to scrollable lists and media gallery ([ThibG](https://github.com/tootsuite/mastodon/pull/9501))
+- Fix bootsnap cache directory being declared relatively ([Gargron](https://github.com/tootsuite/mastodon/pull/9511))
+- Fix timeline pagination in the web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/9516))
+- Fix padding on dropdown elements in preferences ([ThibG](https://github.com/tootsuite/mastodon/pull/9517))
+- Make avatar and headers respect GIF autoplay settings ([ThibG](https://github.com/tootsuite/mastodon/pull/9515))
+- Do no retry Web Push workers if the server returns a 4xx response ([Gargron](https://github.com/tootsuite/mastodon/pull/9434))
+- Minor scrollable list fixes ([ThibG](https://github.com/tootsuite/mastodon/pull/9551))
+- Ignore low-confidence CharlockHolmes guesses when parsing link cards ([ThibG](https://github.com/tootsuite/mastodon/pull/9510))
+- Fix `tootctl accounts rotate` not updating public keys ([Gargron](https://github.com/tootsuite/mastodon/pull/9556))
+- Fix CSP / X-Frame-Options for media players ([jomo](https://github.com/tootsuite/mastodon/pull/9558))
+- Fix unnecessary loadMore calls when the end of a timeline has been reached ([ThibG](https://github.com/tootsuite/mastodon/pull/9581))
+- Skip mailer job retries when a record no longer exists ([Gargron](https://github.com/tootsuite/mastodon/pull/9590))
+- Fix composer not getting focus after reply confirmation dialog ([ThibG](https://github.com/tootsuite/mastodon/pull/9602))
+- Fix signature verification stoplight triggering on non-timeout errors ([Gargron](https://github.com/tootsuite/mastodon/pull/9617))
+- Fix ThreadResolveWorker getting queued with invalid URLs ([Gargron](https://github.com/tootsuite/mastodon/pull/9628))
+- Fix crash when clearing uninitialized timeline ([ThibG](https://github.com/tootsuite/mastodon/pull/9662))
+- Avoid duplicate work by merging ReplyDistributionWorker into DistributionWorker ([ThibG](https://github.com/tootsuite/mastodon/pull/9660))
+- Skip full text search if it fails, instead of erroring out completely ([Kjwon15](https://github.com/tootsuite/mastodon/pull/9654))
+- Fix profile metadata links not verifying correctly sometimes ([shrft](https://github.com/tootsuite/mastodon/pull/9673))
+- Ensure blocked user unfollows blocker if Block/Undo-Block activities are processed out of order ([ThibG](https://github.com/tootsuite/mastodon/pull/9687))
+- Fix unreadable text color in report modal for some statuses ([Gargron](https://github.com/tootsuite/mastodon/pull/9716))
+- Stop GIFV timeline preview explicitly when it's opened in modal ([kedamaDQ](https://github.com/tootsuite/mastodon/pull/9749))
+- Fix scrollbar width compensation ([ThibG](https://github.com/tootsuite/mastodon/pull/9824))
+- Fix race conditions when processing deleted toots ([ThibG](https://github.com/tootsuite/mastodon/pull/9815))
+- Fix SSO issues on WebKit browsers by disabling Same-Site cookie again ([moritzheiber](https://github.com/tootsuite/mastodon/pull/9819))
+- Fix empty OEmbed error ([renatolond](https://github.com/tootsuite/mastodon/pull/9807))
+- Fix drag & drop modal not disappearing sometimes ([hinaloe](https://github.com/tootsuite/mastodon/pull/9797))
+- Fix statuses with content warnings being displayed in web push notifications sometimes ([ThibG](https://github.com/tootsuite/mastodon/pull/9778))
+- Fix scroll-to-detailed status not working on public pages ([ThibG](https://github.com/tootsuite/mastodon/pull/9773))
+- Fix media modal loading indicator ([ThibG](https://github.com/tootsuite/mastodon/pull/9771))
+- Fix hashtag search results not having a permalink fallback in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/9810))
+- Fix slightly cropped font on settings page dropdowns when using system font ([ariasuni](https://github.com/tootsuite/mastodon/pull/9839))
+- Fix not being able to drag & drop text into forms ([tmm576](https://github.com/tootsuite/mastodon/pull/9840))
+
+### Security
+
+- Sanitize and sandbox toot embeds in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/9552))
+- Add tombstones for remote statuses to prevent replay attacks ([ThibG](https://github.com/tootsuite/mastodon/pull/9830))
+
+## [2.6.5] - 2018-12-01
+### Changed
+
+- Change lists to display replies to others on the list and list owner ([ThibG](https://github.com/tootsuite/mastodon/pull/9324))
+
+### Fixed
+
+- Fix failures caused by commonly-used JSON-LD contexts being unavailable ([ThibG](https://github.com/tootsuite/mastodon/pull/9412))
+
+## [2.6.4] - 2018-11-30
+### Fixed
+
+- Fix yarn dependencies not installing due to yanked event-stream package ([Gargron](https://github.com/tootsuite/mastodon/pull/9401))
+
+## [2.6.3] - 2018-11-30
+### Added
+
+- Add hyphen to characters allowed in remote usernames ([ThibG](https://github.com/tootsuite/mastodon/pull/9345))
+
+### Changed
+
+- Change server user count to exclude suspended accounts ([Gargron](https://github.com/tootsuite/mastodon/pull/9380))
+
+### Fixed
+
+- Fix ffmpeg processing sometimes stalling due to overfilled stdout buffer ([hugogameiro](https://github.com/tootsuite/mastodon/pull/9368))
+- Fix missing DNS records raising the wrong kind of exception ([Gargron](https://github.com/tootsuite/mastodon/pull/9379))
+- Fix already queued deliveries still trying to reach inboxes marked as unavailable ([Gargron](https://github.com/tootsuite/mastodon/pull/9358))
+
+### Security
+
+- Fix TLS handshake timeout not being enforced ([Gargron](https://github.com/tootsuite/mastodon/pull/9381))
+
+## [2.6.2] - 2018-11-23
+### Added
+
+- Add Page to whitelisted ActivityPub types ([mbajur](https://github.com/tootsuite/mastodon/pull/9188))
+- Add 20px to column width in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/9227))
+- Add amount of freed disk space in `tootctl media remove` ([Gargron](https://github.com/tootsuite/mastodon/pull/9229), [Gargron](https://github.com/tootsuite/mastodon/pull/9239), [mayaeh](https://github.com/tootsuite/mastodon/pull/9288))
+- Add "Show thread" link to self-replies ([Gargron](https://github.com/tootsuite/mastodon/pull/9228))
+
+### Changed
+
+- Change order of Atom and RSS links so Atom is first ([Alkarex](https://github.com/tootsuite/mastodon/pull/9302))
+- Change Nginx configuration for Nanobox apps ([danhunsaker](https://github.com/tootsuite/mastodon/pull/9310))
+- Change the follow action to appear instant in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/9220))
+- Change how the ActiveRecord connection is instantiated in on_worker_boot ([Gargron](https://github.com/tootsuite/mastodon/pull/9238))
+- Change `tootctl accounts cull` to always touch accounts so they can be skipped ([renatolond](https://github.com/tootsuite/mastodon/pull/9293))
+- Change mime type comparison to ignore JSON-LD profile ([valerauko](https://github.com/tootsuite/mastodon/pull/9179))
+
+### Fixed
+
+- Fix web UI crash when conversation has no last status ([sammy8806](https://github.com/tootsuite/mastodon/pull/9207))
+- Fix follow limit validator reporting lower number past threshold ([Gargron](https://github.com/tootsuite/mastodon/pull/9230))
+- Fix form validation flash message color and input borders ([Gargron](https://github.com/tootsuite/mastodon/pull/9235))
+- Fix invalid twitter:player cards being displayed ([ThibG](https://github.com/tootsuite/mastodon/pull/9254))
+- Fix emoji update date being processed incorrectly ([ThibG](https://github.com/tootsuite/mastodon/pull/9255))
+- Fix playing embed resetting if status is reloaded in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/9270), [Gargron](https://github.com/tootsuite/mastodon/pull/9275))
+- Fix web UI crash when favouriting a deleted status ([ThibG](https://github.com/tootsuite/mastodon/pull/9272))
+- Fix intermediary arrays being created for hash maps ([Gargron](https://github.com/tootsuite/mastodon/pull/9291))
+- Fix filter ID not being a string in REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/9303))
+
+### Security
+
+- Fix multiple remote account deletions being able to deadlock the database ([Gargron](https://github.com/tootsuite/mastodon/pull/9292))
+- Fix HTTP connection timeout of 10s not being enforced ([Gargron](https://github.com/tootsuite/mastodon/pull/9329))
+
+## [2.6.1] - 2018-10-30
+### Fixed
+
+- Fix resolving resources by URL not working due to a regression in [valerauko](https://github.com/tootsuite/mastodon/pull/9132) ([Gargron](https://github.com/tootsuite/mastodon/pull/9171))
+- Fix reducer error in web UI when a conversation has no last status ([Gargron](https://github.com/tootsuite/mastodon/pull/9173))
+
+## [2.6.0] - 2018-10-30
+### Added
+
+- Add link ownership verification ([Gargron](https://github.com/tootsuite/mastodon/pull/8703))
+- Add conversations API ([Gargron](https://github.com/tootsuite/mastodon/pull/8832))
+- Add limit for the number of people that can be followed from one account ([Gargron](https://github.com/tootsuite/mastodon/pull/8807))
+- Add admin setting to customize mascot ([ashleyhull-versent](https://github.com/tootsuite/mastodon/pull/8766))
+- Add support for more granular ActivityPub audiences from other software, i.e. circles ([Gargron](https://github.com/tootsuite/mastodon/pull/8950), [Gargron](https://github.com/tootsuite/mastodon/pull/9093), [Gargron](https://github.com/tootsuite/mastodon/pull/9150))
+- Add option to block all reports from a domain ([Gargron](https://github.com/tootsuite/mastodon/pull/8830))
+- Add user preference to always expand toots marked with content warnings ([webroo](https://github.com/tootsuite/mastodon/pull/8762))
+- Add user preference to always hide all media ([fvh-P](https://github.com/tootsuite/mastodon/pull/8569))
+- Add `force_login` param to OAuth authorize page ([Gargron](https://github.com/tootsuite/mastodon/pull/8655))
+- Add `tootctl accounts backup` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl accounts create` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl accounts cull` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl accounts delete` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl accounts modify` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl accounts refresh` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl feeds build` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl feeds clear` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl settings registrations open` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `tootctl settings registrations close` ([Gargron](https://github.com/tootsuite/mastodon/pull/8642), [Gargron](https://github.com/tootsuite/mastodon/pull/8811))
+- Add `min_id` param to REST API to support backwards pagination ([Gargron](https://github.com/tootsuite/mastodon/pull/8736))
+- Add a confirmation dialog when hitting reply and the compose box isn't empty ([ThibG](https://github.com/tootsuite/mastodon/pull/8893))
+- Add PostgreSQL disk space growth tracking in PGHero ([Gargron](https://github.com/tootsuite/mastodon/pull/8906))
+- Add button for disabling local account to report quick actions bar ([Gargron](https://github.com/tootsuite/mastodon/pull/9024))
+- Add Czech language ([Aditoo17](https://github.com/tootsuite/mastodon/pull/8594))
+- Add `same-site` (`lax`) attribute to cookies ([sorin-davidoi](https://github.com/tootsuite/mastodon/pull/8626))
+- Add support for styled scrollbars in Firefox Nightly ([sorin-davidoi](https://github.com/tootsuite/mastodon/pull/8653))
+- Add highlight to the active tab in web UI profiles ([rhoio](https://github.com/tootsuite/mastodon/pull/8673))
+- Add auto-focus for comment textarea in report modal ([ThibG](https://github.com/tootsuite/mastodon/pull/8689))
+- Add auto-focus for emoji picker's search field ([ThibG](https://github.com/tootsuite/mastodon/pull/8688))
+- Add nginx and systemd templates to `dist/` directory ([Gargron](https://github.com/tootsuite/mastodon/pull/8770))
+- Add support for `/.well-known/change-password` ([Gargron](https://github.com/tootsuite/mastodon/pull/8828))
+- Add option to override FFMPEG binary path ([sascha-sl](https://github.com/tootsuite/mastodon/pull/8855))
+- Add `dns-prefetch` tag when using different host for assets or uploads ([Gargron](https://github.com/tootsuite/mastodon/pull/8942))
+- Add `description` meta tag ([Gargron](https://github.com/tootsuite/mastodon/pull/8941))
+- Add `Content-Security-Policy` header ([ThibG](https://github.com/tootsuite/mastodon/pull/8957))
+- Add cache for the instance info API ([ykzts](https://github.com/tootsuite/mastodon/pull/8765))
+- Add suggested follows to search screen in mobile layout ([Gargron](https://github.com/tootsuite/mastodon/pull/9010))
+- Add CORS header to `/.well-known/*` routes ([BenLubar](https://github.com/tootsuite/mastodon/pull/9083))
+- Add `card` attribute to statuses returned from REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/9120))
+- Add in-stream link preview ([Gargron](https://github.com/tootsuite/mastodon/pull/9120))
+- Add support for ActivityPub `Page` objects ([mbajur](https://github.com/tootsuite/mastodon/pull/9121))
+
+### Changed
+
+- Change forms design ([Gargron](https://github.com/tootsuite/mastodon/pull/8703))
+- Change reports overview to group by target account ([Gargron](https://github.com/tootsuite/mastodon/pull/8674))
+- Change web UI to show "read more" link on overly long in-stream statuses ([lanodan](https://github.com/tootsuite/mastodon/pull/8205))
+- Change design of direct messages column ([Gargron](https://github.com/tootsuite/mastodon/pull/8832), [Gargron](https://github.com/tootsuite/mastodon/pull/9022))
+- Change home timelines to exclude DMs ([Gargron](https://github.com/tootsuite/mastodon/pull/8940))
+- Change list timelines to exclude all replies ([cbayerlein](https://github.com/tootsuite/mastodon/pull/8683))
+- Change admin accounts UI default sort to most recent ([Gargron](https://github.com/tootsuite/mastodon/pull/8813))
+- Change documentation URL in the UI ([Gargron](https://github.com/tootsuite/mastodon/pull/8898))
+- Change style of success and failure messages ([Gargron](https://github.com/tootsuite/mastodon/pull/8973))
+- Change DM filtering to always allow DMs from staff ([qguv](https://github.com/tootsuite/mastodon/pull/8993))
+- Change recommended Ruby version to 2.5.3 ([zunda](https://github.com/tootsuite/mastodon/pull/9003))
+- Change docker-compose default to persist volumes in current directory ([Gargron](https://github.com/tootsuite/mastodon/pull/9055))
+- Change character counters on edit profile page to input length limit ([Gargron](https://github.com/tootsuite/mastodon/pull/9100))
+- Change notification filtering to always let through messages from staff ([Gargron](https://github.com/tootsuite/mastodon/pull/9152))
+- Change "hide boosts from user" function also hiding notifications about boosts ([ThibG](https://github.com/tootsuite/mastodon/pull/9147))
+- Change CSS `detailed-status__wrapper` class actually wrap the detailed status ([trwnh](https://github.com/tootsuite/mastodon/pull/8547))
+
+### Deprecated
+
+- `GET /api/v1/timelines/direct` → `GET /api/v1/conversations` ([Gargron](https://github.com/tootsuite/mastodon/pull/8832))
+- `POST /api/v1/notifications/dismiss` → `POST /api/v1/notifications/:id/dismiss` ([Gargron](https://github.com/tootsuite/mastodon/pull/8905))
+- `GET /api/v1/statuses/:id/card` → `card` attributed included in status ([Gargron](https://github.com/tootsuite/mastodon/pull/9120))
+
+### Removed
+
+- Remove "on this device" label in column push settings ([rhoio](https://github.com/tootsuite/mastodon/pull/8704))
+- Remove rake tasks in favour of tootctl commands ([Gargron](https://github.com/tootsuite/mastodon/pull/8675))
+
+### Fixed
+
+- Fix remote statuses using instance's default locale if no language given ([Kjwon15](https://github.com/tootsuite/mastodon/pull/8861))
+- Fix streaming API not exiting when port or socket is unavailable ([Gargron](https://github.com/tootsuite/mastodon/pull/9023))
+- Fix network calls being performed in database transaction in ActivityPub handler ([Gargron](https://github.com/tootsuite/mastodon/pull/8951))
+- Fix dropdown arrow position ([ThibG](https://github.com/tootsuite/mastodon/pull/8637))
+- Fix first element of dropdowns being focused even if not using keyboard ([ThibG](https://github.com/tootsuite/mastodon/pull/8679))
+- Fix tootctl requiring `bundle exec` invocation ([abcang](https://github.com/tootsuite/mastodon/pull/8619))
+- Fix public pages not using animation preference for avatars ([renatolond](https://github.com/tootsuite/mastodon/pull/8614))
+- Fix OEmbed/OpenGraph cards not understanding relative URLs ([ThibG](https://github.com/tootsuite/mastodon/pull/8669))
+- Fix some dark emojis not having a white outline ([ThibG](https://github.com/tootsuite/mastodon/pull/8597))
+- Fix media description not being displayed in various media modals ([ThibG](https://github.com/tootsuite/mastodon/pull/8678))
+- Fix generated URLs of desktop notifications missing base URL ([GenbuHase](https://github.com/tootsuite/mastodon/pull/8758))
+- Fix RTL styles ([mabkenar](https://github.com/tootsuite/mastodon/pull/8764), [mabkenar](https://github.com/tootsuite/mastodon/pull/8767), [mabkenar](https://github.com/tootsuite/mastodon/pull/8823), [mabkenar](https://github.com/tootsuite/mastodon/pull/8897), [mabkenar](https://github.com/tootsuite/mastodon/pull/9005), [mabkenar](https://github.com/tootsuite/mastodon/pull/9007), [mabkenar](https://github.com/tootsuite/mastodon/pull/9018), [mabkenar](https://github.com/tootsuite/mastodon/pull/9021), [mabkenar](https://github.com/tootsuite/mastodon/pull/9145), [mabkenar](https://github.com/tootsuite/mastodon/pull/9146))
+- Fix crash in streaming API when tag param missing ([Gargron](https://github.com/tootsuite/mastodon/pull/8955))
+- Fix hotkeys not working when no element is focused ([ThibG](https://github.com/tootsuite/mastodon/pull/8998))
+- Fix some hotkeys not working on detailed status view ([ThibG](https://github.com/tootsuite/mastodon/pull/9006))
+- Fix og:url on status pages ([ThibG](https://github.com/tootsuite/mastodon/pull/9047))
+- Fix upload option buttons only being visible on hover ([Gargron](https://github.com/tootsuite/mastodon/pull/9074))
+- Fix tootctl not returning exit code 1 on wrong arguments ([sascha-sl](https://github.com/tootsuite/mastodon/pull/9094))
+- Fix preview cards for appearing for profiles mentioned in toot ([ThibG](https://github.com/tootsuite/mastodon/pull/6934), [ThibG](https://github.com/tootsuite/mastodon/pull/9158))
+- Fix local accounts sometimes being duplicated as faux-remote ([Gargron](https://github.com/tootsuite/mastodon/pull/9109))
+- Fix emoji search when the shortcode has multiple separators ([ThibG](https://github.com/tootsuite/mastodon/pull/9124))
+- Fix dropdowns sometimes being partially obscured by other elements ([kedamaDQ](https://github.com/tootsuite/mastodon/pull/9126))
+- Fix cache not updating when reply/boost/favourite counters or media sensitivity update ([Gargron](https://github.com/tootsuite/mastodon/pull/9119))
+- Fix empty display name precedence over username in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/9163))
+- Fix td instead of th in sessions table header ([Gargron](https://github.com/tootsuite/mastodon/pull/9162))
+- Fix handling of content types with profile ([valerauko](https://github.com/tootsuite/mastodon/pull/9132))
+
+## [2.5.2] - 2018-10-12
+### Security
+
+- Fix XSS vulnerability ([Gargron](https://github.com/tootsuite/mastodon/pull/8959))
+
+## [2.5.1] - 2018-10-07
+### Fixed
+
+- Fix database migrations for PostgreSQL below 9.5 ([Gargron](https://github.com/tootsuite/mastodon/pull/8903))
+- Fix class autoloading issue in ActivityPub Create handler ([Gargron](https://github.com/tootsuite/mastodon/pull/8820))
+- Fix cache statistics not being sent via statsd when statsd enabled ([ykzts](https://github.com/tootsuite/mastodon/pull/8831))
+- Bump puma from 3.11.4 to 3.12.0 ([dependabot[bot]](https://github.com/tootsuite/mastodon/pull/8883))
+
+### Security
+
+- Fix some local images not having their EXIF metadata stripped on upload ([ThibG](https://github.com/tootsuite/mastodon/pull/8714))
+- Fix being able to enable a disabled relay via ActivityPub Accept handler ([ThibG](https://github.com/tootsuite/mastodon/pull/8864))
+- Bump nokogiri from 1.8.4 to 1.8.5 ([dependabot[bot]](https://github.com/tootsuite/mastodon/pull/8881))
+- Fix being able to report statuses not belonging to the reported account ([ThibG](https://github.com/tootsuite/mastodon/pull/8916))
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d0f75f2e453fc3067f4e1c527771260e7dce8ddc..b55729a9ba2da8ef06eed1f26f10f89092f81148 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,56 +1,37 @@
-CONTRIBUTING
+Contributing
 ============
 
-There are three ways in which you can contribute to this repository:
+Thank you for considering contributing to Mastodon 🐘 
 
-1. By improving the documentation
-2. By working on the back-end application
-3. By working on the front-end application
+You can contribute in the following ways:
 
-Choosing what to work on in a large open source project is not easy. The list of [GitHub issues](https://github.com/tootsuite/mastodon/issues) may provide some ideas, but not every feature request has been greenlit. Likewise, not every change or feature that resolves a personal itch will be merged into the main repository. Some communication ahead of time may be wise. If your addition creates a new feature or setting, or otherwise changes how things work in some substantial way, please remember to submit a correlating pull request to document your changes in the [documentation](http://github.com/tootsuite/documentation).
+- Finding and reporting bugs
+- Translating the Mastodon interface into various languages
+- Contributing code to Mastodon by fixing bugs or implementing features
+- Improving the documentation
 
-Below are the guidelines for working on pull requests:
+## Bug reports
 
-## General
+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.
 
-- 2 spaces indentation
+## Translations
 
-## Documentation
-
-- No spelling mistakes
-- No orthographic mistakes
-- No Markdown syntax errors
-
-## Requirements
-
-- Ruby
-- Node.js
-- PostgreSQL
-- Redis
-- Nginx (optional)
-
-## Back-end application
+You can submit translations via [Weblate](https://weblate.joinmastodon.org/). They are periodically merged into the codebase.
 
-It is expected that you have a working development environment set up. The development environment includes [rubocop](https://github.com/bbatsov/rubocop), which checks your Ruby code for compliance with our style guide and best practices. Sublime Text, likely like other editors, has a [Rubocop plugin](https://github.com/pderichs/sublime_rubocop) that runs checks on files as you edit them. The codebase also has a test suite.
-
-* The codebase is not perfect, at the time of writing, but it is expected that you do not introduce new code style violations
-* The rspec test suite must pass
-* To the extent that it is possible, verify your changes. In the best case, by adding new tests to the test suite. At the very least, by running the server or console and checking it manually
-* If you are introducing new strings to the user interface, they must be using localization methods
+[![Mastodon translation statistics by language](https://weblate.joinmastodon.org/widgets/mastodon/-/multi-auto.svg)](https://weblate.joinmastodon.org/)
 
-If your code has syntax errors that won't let it run, it's a good sign that the pull request isn't ready for submission yet.
+## Pull requests
 
-## Front-end application
+Please use clean, concise titles for your pull requests. We use commit squashing, so the final commit in the master branch will carry the title of the pull request.
 
-It is expected that you have a working development environment set up (see back-end application section). This project includes an ESLint configuration file, with which you can lint your changes.
+The smaller the set of changes in the pull request is, the quicker it can be reviewed and merged. Splitting tasks into multiple smaller pull requests is often preferable.
 
-* Avoid grave ESLint violations
-* Verify that your changes work
-* If you are introducing new strings, they must be using localization methods
+**Pull requests that do not pass automated checks may not be reviewed**. In particular, you need to keep in mind:
 
-If the JavaScript or CSS assets won't compile due to a syntax error, it's a good sign that the pull request isn't ready for submission yet.
+- Unit and integration tests (rspec, jest)
+- Code style rules (rubocop, eslint)
+- Normalization of locale files (i18n-tasks)
 
-## Translate
+## Documentation
 
-You can contribute to translating Mastodon via Weblate at [weblate.joinmastodon.org](https://weblate.joinmastodon.org/).
-[![Mastodon translation statistics by language](https://weblate.joinmastodon.org/widgets/mastodon/-/multi-auto.svg)](https://weblate.joinmastodon.org/)
+The [Mastodon documentation](https://docs.joinmastodon.org) is a statically generated site. You can [submit merge requests to mastodon/docs](https://source.joinmastodon.org/mastodon/docs).
diff --git a/Dockerfile b/Dockerfile
index fe1cea89a42a08dedd4974ac5439e3d17d3b49ad..19090533757c5260aff2366a962498734bd5983f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,5 @@
-FROM ruby:2.4.4-alpine3.6
+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"
@@ -11,8 +12,6 @@ ENV PATH=/mastodon/bin:$PATH \
     RAILS_ENV=production \
     NODE_ENV=production
 
-ARG YARN_VERSION=1.3.2
-ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d
 ARG LIBICONV_VERSION=1.15
 ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
 
@@ -20,6 +19,11 @@ 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 \
@@ -27,6 +31,8 @@ RUN apk -U upgrade \
     libidn-dev \
     libressl \
     libtool \
+    libxml2-dev \
+    libxslt-dev \
     postgresql-dev \
     protobuf-dev \
     python \
@@ -39,20 +45,15 @@ RUN apk -U upgrade \
     imagemagick \
     libidn \
     libpq \
-    nodejs \
-    nodejs-npm \
+    libxml2 \
+    libxslt \
     protobuf \
     tini \
     tzdata \
  && update-ca-certificates \
- && mkdir -p /tmp/src /opt \
- && wget -O yarn.tar.gz "https://github.com/yarnpkg/yarn/releases/download/v$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
- && echo "$YARN_DOWNLOAD_SHA256 *yarn.tar.gz" | sha256sum -c - \
- && tar -xzf yarn.tar.gz -C /tmp/src \
- && rm yarn.tar.gz \
- && mv /tmp/src/yarn-v$YARN_VERSION /opt/yarn \
  && 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 \
@@ -67,9 +68,9 @@ RUN apk -U upgrade \
 
 COPY Gemfile Gemfile.lock package.json yarn.lock .yarnclean /mastodon/
 
-RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \
+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 --pure-lockfile \
+ && 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 \
@@ -80,8 +81,10 @@ COPY . /mastodon
 
 RUN chown -R mastodon:mastodon /mastodon
 
-VOLUME /mastodon/public/system /mastodon/public/assets /mastodon/public/packs
+VOLUME /mastodon/public/system
 
 USER mastodon
 
+RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile
+
 ENTRYPOINT ["/sbin/tini", "--"]
diff --git a/Gemfile b/Gemfile
index 7a6e1568d28c355b09bc3d778b4c8c272c6135cf..d17ff1a51c3820b8e8ed4481a2296df385e7950f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,138 +1,139 @@
 # frozen_string_literal: true
 
 source 'https://rubygems.org'
-ruby '>= 2.3.0', '< 2.6.0'
+ruby '>= 2.4.0', '< 2.7.0'
 
 gem 'pkg-config', '~> 1.3'
 
-gem 'puma', '~> 3.11'
-gem 'rails', '~> 5.2.0'
+gem 'puma', '~> 3.12'
+gem 'rails', '~> 5.2.2'
+gem 'thor', '~> 0.20'
 
 gem 'hamlit-rails', '~> 0.2'
-gem 'pg', '~> 1.0'
-gem 'pghero', '~> 2.1'
-gem 'dotenv-rails', '~> 2.2', '< 2.3'
-
-gem 'aws-sdk-s3', '~> 1.9', require: false
-gem 'fog-core', '~> 1.45'
-gem 'fog-local', '~> 0.5', require: false
-gem 'fog-openstack', '~> 0.1', require: false
+gem 'pg', '~> 1.1'
+gem 'makara', '~> 0.4'
+gem 'pghero', '~> 2.2'
+gem 'dotenv-rails', '~> 2.6'
+
+gem 'aws-sdk-s3', '~> 1.30', 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 'active_model_serializers', '~> 0.10'
 gem 'addressable', '~> 2.5'
-gem 'bootsnap', '~> 1.3'
+gem 'bootsnap', '~> 1.3', require: false
 gem 'browser'
 gem 'charlock_holmes', '~> 0.7.6'
 gem 'iso-639'
 gem 'chewy', '~> 5.0'
-gem 'cld3', '~> 3.2.0'
-gem 'devise', '~> 4.4'
+gem 'cld3', '~> 3.2.3'
+gem 'devise', '~> 4.5'
 gem 'devise-two-factor', '~> 3.0'
 
 group :pam_authentication, optional: true do
-  gem 'devise_pam_authenticatable2', '~> 9.1'
+  gem 'devise_pam_authenticatable2', '~> 9.2'
 end
 
 gem 'net-ldap', '~> 0.10'
 gem 'omniauth-cas', '~> 1.1'
 gem 'omniauth-saml', '~> 1.10'
-gem 'omniauth', '~> 1.2'
+gem 'omniauth', '~> 1.9'
 
-gem 'doorkeeper', '~> 4.2', '< 4.3'
+gem 'doorkeeper', '~> 5.0'
 gem 'fast_blank', '~> 1.0'
 gem 'fastimage'
 gem 'goldfinger', '~> 2.1'
 gem 'hiredis', '~> 0.6'
 gem 'redis-namespace', '~> 1.5'
 gem 'htmlentities', '~> 4.3'
-gem 'http', '~> 3.2'
+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.0'
+gem 'httplog', '~> 1.2'
 gem 'idn-ruby', require: 'idn'
 gem 'kaminari', '~> 1.1'
 gem 'link_header', '~> 0.0'
-gem 'mime-types', '~> 3.1', require: 'mime/types/columnar'
-gem 'nokogiri', '~> 1.8'
+gem 'mime-types', '~> 3.2', require: 'mime/types/columnar'
+gem 'nokogiri', '~> 1.10'
 gem 'nsa', '~> 0.2'
-gem 'oj', '~> 3.5'
+gem 'oj', '~> 3.7'
 gem 'ostatus2', '~> 2.0'
-gem 'ox', '~> 2.9'
+gem 'ox', '~> 2.10'
 gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
-gem 'pundit', '~> 1.1'
+gem 'pundit', '~> 2.0'
 gem 'premailer-rails'
-gem 'rack-attack', '~> 5.2'
+gem 'rack-attack', '~> 5.4'
 gem 'rack-cors', '~> 1.0', require: 'rack/cors'
 gem 'rails-i18n', '~> 5.1'
 gem 'rails-settings-cached', '~> 0.6'
-gem 'redis', '~> 4.0', require: ['redis', 'redis/connection/hiredis']
+gem 'redis', '~> 4.1', require: ['redis', 'redis/connection/hiredis']
 gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
 gem 'rqrcode', '~> 0.10'
-gem 'ruby-progressbar', '~> 1.4'
-gem 'sanitize', '~> 4.6'
-gem 'sidekiq', '~> 5.1'
-gem 'sidekiq-scheduler', '~> 2.2'
-gem 'sidekiq-unique-jobs', '~> 5.0'
-gem 'sidekiq-bulk', '~>0.1.1'
+gem 'sanitize', '~> 5.0'
+gem 'sidekiq', '~> 5.2'
+gem 'sidekiq-scheduler', '~> 3.0'
+gem 'sidekiq-unique-jobs', '~> 6.0'
+gem 'sidekiq-bulk', '~>0.2.0'
 gem 'simple-navigation', '~> 4.0'
-gem 'simple_form', '~> 4.0'
+gem 'simple_form', '~> 4.1'
 gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
 gem 'stoplight', '~> 2.1.3'
-gem 'strong_migrations', '~> 0.2'
+gem 'strong_migrations', '~> 0.3'
 gem 'tty-command', '~> 0.8', require: false
-gem 'tty-prompt', '~> 0.16', require: false
+gem 'tty-prompt', '~> 0.18', require: false
 gem 'twitter-text', '~> 1.14'
 gem 'tzinfo-data', '~> 1.2018'
-gem 'webpacker', '~> 3.4'
+gem 'webpacker', '~> 3.5'
 gem 'webpush'
 
-gem 'json-ld', '~> 2.2'
+gem 'json-ld', '~> 3.0'
+gem 'json-ld-preloaded', '~> 3.0'
 gem 'rdf-normalize', '~> 0.3'
 
 group :development, :test do
   gem 'fabrication', '~> 2.20'
-  gem 'fuubar', '~> 2.2'
+  gem 'fuubar', '~> 2.3'
   gem 'i18n-tasks', '~> 0.9', require: false
   gem 'pry-byebug', '~> 3.6'
   gem 'pry-rails', '~> 0.3'
-  gem 'rspec-rails', '~> 3.7'
+  gem 'rspec-rails', '~> 3.8'
 end
 
 group :production, :test do
-  gem 'private_address_check', '~> 0.4.1'
+  gem 'private_address_check', '~> 0.5'
 end
 
 group :test do
-  gem 'capybara', '~> 2.18'
+  gem 'capybara', '~> 3.12'
   gem 'climate_control', '~> 0.2'
-  gem 'faker', '~> 1.8'
+  gem 'faker', '~> 1.9'
   gem 'microformats', '~> 4.0'
   gem 'rails-controller-testing', '~> 1.0'
   gem 'rspec-sidekiq', '~> 3.0'
   gem 'simplecov', '~> 0.16', require: false
-  gem 'webmock', '~> 3.3'
-  gem 'parallel_tests', '~> 2.21'
+  gem 'webmock', '~> 3.5'
+  gem 'parallel_tests', '~> 2.27'
 end
 
 group :development do
   gem 'active_record_query_trace', '~> 1.5'
   gem 'annotate', '~> 2.7'
-  gem 'better_errors', '~> 2.4'
+  gem 'better_errors', '~> 2.5'
   gem 'binding_of_caller', '~> 0.7'
-  gem 'bullet', '~> 5.7'
-  gem 'letter_opener', '~> 1.4'
+  gem 'bullet', '~> 5.9'
+  gem 'letter_opener', '~> 1.7'
   gem 'letter_opener_web', '~> 1.3'
   gem 'memory_profiler'
-  gem 'rubocop', '~> 0.55', require: false
-  gem 'brakeman', '~> 4.2', require: false
+  gem 'rubocop', '~> 0.63', require: false
+  gem 'brakeman', '~> 4.4', require: false
   gem 'bundler-audit', '~> 0.6', require: false
   gem 'scss_lint', '~> 0.57', require: false
 
-  gem 'capistrano', '~> 3.10'
-  gem 'capistrano-rails', '~> 1.3'
+  gem 'capistrano', '~> 3.11'
+  gem 'capistrano-rails', '~> 1.4'
   gem 'capistrano-rbenv', '~> 2.1'
   gem 'capistrano-yarn', '~> 2.0'
 
@@ -144,3 +145,5 @@ group :production do
   gem 'lograge', '~> 0.10'
   gem 'redis-rails', '~> 5.0'
 end
+
+gem 'concurrent-ruby', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index e1929a05c83069691dda609af022755060798f6c..acb4b8dda98fe5377ec88c9a2767fc66ce0fac8b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -15,49 +15,49 @@ GIT
 GEM
   remote: https://rubygems.org/
   specs:
-    actioncable (5.2.0)
-      actionpack (= 5.2.0)
+    actioncable (5.2.2)
+      actionpack (= 5.2.2)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
-    actionmailer (5.2.0)
-      actionpack (= 5.2.0)
-      actionview (= 5.2.0)
-      activejob (= 5.2.0)
+    actionmailer (5.2.2)
+      actionpack (= 5.2.2)
+      actionview (= 5.2.2)
+      activejob (= 5.2.2)
       mail (~> 2.5, >= 2.5.4)
       rails-dom-testing (~> 2.0)
-    actionpack (5.2.0)
-      actionview (= 5.2.0)
-      activesupport (= 5.2.0)
+    actionpack (5.2.2)
+      actionview (= 5.2.2)
+      activesupport (= 5.2.2)
       rack (~> 2.0)
       rack-test (>= 0.6.3)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.0.2)
-    actionview (5.2.0)
-      activesupport (= 5.2.0)
+    actionview (5.2.2)
+      activesupport (= 5.2.2)
       builder (~> 3.1)
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.0.3)
-    active_model_serializers (0.10.7)
+    active_model_serializers (0.10.8)
       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.0)
-      activesupport (= 5.2.0)
+    activejob (5.2.2)
+      activesupport (= 5.2.2)
       globalid (>= 0.3.6)
-    activemodel (5.2.0)
-      activesupport (= 5.2.0)
-    activerecord (5.2.0)
-      activemodel (= 5.2.0)
-      activesupport (= 5.2.0)
+    activemodel (5.2.2)
+      activesupport (= 5.2.2)
+    activerecord (5.2.2)
+      activemodel (= 5.2.2)
+      activesupport (= 5.2.2)
       arel (>= 9.0)
-    activestorage (5.2.0)
-      actionpack (= 5.2.0)
-      activerecord (= 5.2.0)
+    activestorage (5.2.2)
+      actionpack (= 5.2.2)
+      activerecord (= 5.2.2)
       marcel (~> 0.3.1)
-    activesupport (5.2.0)
+    activesupport (5.2.2)
       concurrent-ruby (~> 1.0, >= 1.0.2)
       i18n (>= 0.7, < 2)
       minitest (~> 5.1)
@@ -66,7 +66,7 @@ GEM
       public_suffix (>= 2.0.2, < 4.0)
     airbrussh (1.3.0)
       sshkit (>= 1.6.1, != 1.7.0)
-    annotate (2.7.3)
+    annotate (2.7.4)
       activerecord (>= 3.2, < 6.0)
       rake (>= 10.4, < 13.0)
     arel (9.0.0)
@@ -75,40 +75,42 @@ GEM
       encryptor (~> 3.0.0)
     av (0.9.0)
       cocaine (~> 0.5.3)
-    aws-partitions (1.80.0)
-    aws-sdk-core (3.19.0)
+    aws-eventstream (1.0.1)
+    aws-partitions (1.131.0)
+    aws-sdk-core (3.45.0)
+      aws-eventstream (~> 1.0)
       aws-partitions (~> 1.0)
       aws-sigv4 (~> 1.0)
       jmespath (~> 1.0)
-    aws-sdk-kms (1.5.0)
-      aws-sdk-core (~> 3)
+    aws-sdk-kms (1.13.0)
+      aws-sdk-core (~> 3, >= 3.39.0)
       aws-sigv4 (~> 1.0)
-    aws-sdk-s3 (1.9.1)
-      aws-sdk-core (~> 3)
+    aws-sdk-s3 (1.30.1)
+      aws-sdk-core (~> 3, >= 3.39.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.0)
-    aws-sigv4 (1.0.2)
+    aws-sigv4 (1.0.3)
     bcrypt (3.1.12)
     benchmark-ips (2.7.2)
-    better_errors (2.4.0)
+    better_errors (2.5.0)
       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.0)
+    bootsnap (1.3.2)
       msgpack (~> 1.0)
-    brakeman (4.2.1)
+    brakeman (4.4.0)
     browser (2.5.3)
     builder (3.2.3)
-    bullet (5.7.5)
+    bullet (5.9.0)
       activesupport (>= 3.0.0)
-      uniform_notifier (~> 1.11.0)
-    bundler-audit (0.6.0)
-      bundler (~> 1.2)
+      uniform_notifier (~> 1.11)
+    bundler-audit (0.6.1)
+      bundler (>= 1.2.0, < 3)
       thor (~> 0.18)
     byebug (10.0.2)
-    capistrano (3.10.2)
+    capistrano (3.11.0)
       airbrussh (>= 1.0.0)
       i18n
       rake (>= 10.0.0)
@@ -116,21 +118,22 @@ GEM
     capistrano-bundler (1.3.0)
       capistrano (~> 3.1)
       sshkit (~> 1.2)
-    capistrano-rails (1.3.1)
+    capistrano-rails (1.4.0)
       capistrano (~> 3.1)
       capistrano-bundler (~> 1.1)
-    capistrano-rbenv (2.1.3)
+    capistrano-rbenv (2.1.4)
       capistrano (~> 3.1)
       sshkit (~> 1.3)
     capistrano-yarn (2.0.2)
       capistrano (~> 3.0)
-    capybara (2.18.0)
+    capybara (3.12.0)
       addressable
       mini_mime (>= 0.1.3)
-      nokogiri (>= 1.3.3)
-      rack (>= 1.0.0)
-      rack-test (>= 0.5.4)
-      xpath (>= 2.0, < 4.0)
+      nokogiri (~> 1.8)
+      rack (>= 1.6.0)
+      rack-test (>= 0.6.3)
+      regexp_parser (~> 1.2)
+      xpath (~> 3.2)
     case_transform (0.2)
       activesupport
     charlock_holmes (0.7.6)
@@ -139,22 +142,21 @@ GEM
       elasticsearch (>= 2.0.0)
       elasticsearch-dsl
     chunky_png (1.3.10)
-    cld3 (3.2.2)
+    cld3 (3.2.3)
       ffi (>= 1.1.0, < 1.10.0)
     climate_control (0.2.0)
     cocaine (0.5.8)
       climate_control (>= 0.0.3, < 1.0)
     coderay (1.1.2)
-    colorize (0.8.1)
-    concurrent-ruby (1.0.5)
-    connection_pool (2.2.1)
+    concurrent-ruby (1.1.4)
+    connection_pool (2.2.2)
     crack (0.4.3)
       safe_yaml (~> 1.0.0)
     crass (1.0.4)
     css_parser (1.6.0)
       addressable
     debug_inspector (0.0.3)
-    derailed_benchmarks (1.3.4)
+    derailed_benchmarks (1.3.5)
       benchmark-ips (~> 2)
       get_process_mem (~> 0)
       heapy (~> 0)
@@ -162,7 +164,7 @@ GEM
       rack (>= 1)
       rake (> 10, < 13)
       thor (~> 0.19)
-    devise (4.4.3)
+    devise (4.5.0)
       bcrypt (~> 3.0)
       orm_adapter (~> 0.1)
       railties (>= 4.1.0, < 6.0)
@@ -174,22 +176,19 @@ GEM
       devise (~> 4.0)
       railties (< 5.3)
       rotp (~> 2.0)
-    devise_pam_authenticatable2 (9.1.0)
+    devise_pam_authenticatable2 (9.2.0)
       devise (>= 4.0.0)
       rpam2 (~> 4.0)
     diff-lcs (1.3)
     docile (1.3.0)
     domain_name (0.5.20180417)
       unf (>= 0.0.5, < 1.0.0)
-    doorkeeper (4.2.6)
+    doorkeeper (5.0.2)
       railties (>= 4.2)
-    dotenv (2.2.2)
-    dotenv-rails (2.2.2)
-      dotenv (= 2.2.2)
+    dotenv (2.6.0)
+    dotenv-rails (2.6.0)
+      dotenv (= 2.6.0)
       railties (>= 3.2, < 6.0)
-    easy_translate (0.5.1)
-      thread
-      thread_safe
     elasticsearch (6.0.2)
       elasticsearch-api (= 6.0.2)
       elasticsearch-transport (= 6.0.2)
@@ -201,36 +200,38 @@ GEM
       multi_json
     encryptor (3.0.0)
     equatable (0.5.0)
-    erubi (1.7.1)
-    et-orbi (1.1.0)
+    erubi (1.8.0)
+    et-orbi (1.1.6)
       tzinfo
     excon (0.62.0)
     fabrication (2.20.1)
-    faker (1.8.7)
+    faker (1.9.1)
       i18n (>= 0.7)
     faraday (0.15.0)
       multipart-post (>= 1.2, < 3)
     fast_blank (1.0.0)
-    fastimage (2.1.1)
-    ffi (1.9.23)
-    fog-core (1.45.0)
+    fastimage (2.1.5)
+    ffi (1.9.25)
+    fog-core (2.1.0)
       builder
       excon (~> 0.58)
       formatador (~> 0.2)
-    fog-json (1.0.2)
-      fog-core (~> 1.0)
+      mime-types
+    fog-json (1.2.0)
+      fog-core
       multi_json (~> 1.10)
-    fog-local (0.5.0)
-      fog-core (>= 1.27, < 3.0)
-    fog-openstack (0.1.25)
-      fog-core (~> 1.40)
+    fog-openstack (0.3.7)
+      fog-core (>= 1.45, <= 2.1.0)
       fog-json (>= 1.0)
       ipaddress (>= 0.8)
     formatador (0.2.5)
-    fuubar (2.3.1)
+    fugit (1.1.6)
+      et-orbi (~> 1.1, >= 1.1.6)
+      raabro (~> 1.1)
+    fuubar (2.3.2)
       rspec-core (~> 3.0)
       ruby-progressbar (~> 1.4)
-    get_process_mem (0.2.1)
+    get_process_mem (0.2.3)
     globalid (0.4.1)
       activesupport (>= 4.2.0)
     goldfinger (2.1.0)
@@ -250,45 +251,49 @@ GEM
     hamster (3.0.0)
       concurrent-ruby (~> 1.0)
     hashdiff (0.3.7)
-    hashie (3.5.7)
-    heapy (0.1.3)
-    highline (1.7.10)
-    hiredis (0.6.1)
-    hitimes (1.2.6)
+    hashie (3.6.0)
+    heapy (0.1.4)
+    highline (2.0.0)
+    hiredis (0.6.3)
     hkdf (0.3.0)
     htmlentities (4.3.4)
-    http (3.2.0)
+    http (3.3.0)
       addressable (~> 2.3)
       http-cookie (~> 1.0)
       http-form_data (~> 2.0)
       http_parser.rb (~> 0.6.0)
     http-cookie (1.0.3)
       domain_name (~> 0.5)
-    http-form_data (2.1.0)
+    http-form_data (2.1.1)
     http_accept_language (2.1.1)
-    httplog (1.0.2)
-      colorize (~> 0.8)
+    httplog (1.2.0)
       rack (>= 1.0)
-    i18n (1.0.1)
+      rainbow (>= 2.0.0)
+    i18n (1.5.2)
       concurrent-ruby (~> 1.0)
-    i18n-tasks (0.9.21)
+    i18n-tasks (0.9.28)
       activesupport (>= 4.0.2)
       ast (>= 2.1.0)
-      easy_translate (>= 0.5.1)
       erubi
-      highline (>= 1.7.3)
+      highline (>= 2.0.0)
       i18n
       parser (>= 2.2.3.0)
+      rails-i18n
       rainbow (>= 2.2.2, < 4.0)
       terminal-table (>= 1.5.1)
     idn-ruby (0.1.0)
     ipaddress (0.8.3)
     iso-639 (0.2.8)
+    jaro_winkler (1.5.2)
     jmespath (1.4.0)
     json (2.1.0)
-    json-ld (2.2.1)
+    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)
+      multi_json (~> 1.12)
+      rdf (~> 3.0)
     jsonapi-renderer (0.2.0)
     jwt (2.1.0)
     kaminari (1.1.1)
@@ -305,7 +310,7 @@ GEM
     kaminari-core (1.1.1)
     launchy (2.4.3)
       addressable (~> 2.3)
-    letter_opener (1.6.0)
+    letter_opener (1.7.0)
       launchy (~> 2.2)
     letter_opener_web (1.3.4)
       actionmailer (>= 3.2)
@@ -317,26 +322,28 @@ GEM
       activesupport (>= 4)
       railties (>= 4)
       request_store (~> 1.0)
-    loofah (2.2.2)
+    loofah (2.2.3)
       crass (~> 1.0.2)
       nokogiri (>= 1.5.9)
-    mail (2.7.0)
+    mail (2.7.1)
       mini_mime (>= 0.1.1)
-    marcel (0.3.2)
+    makara (0.4.0)
+      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.10)
-    method_source (0.9.0)
+    memory_profiler (0.9.12)
+    method_source (0.9.2)
     microformats (4.0.7)
       json
       nokogiri
-    mime-types (3.1)
+    mime-types (3.2.2)
       mime-types-data (~> 3.2015)
-    mime-types-data (3.2016.0521)
+    mime-types-data (3.2018.0812)
     mimemagic (0.3.2)
-    mini_mime (1.0.0)
-    mini_portile2 (2.3.0)
+    mini_mime (1.0.1)
+    mini_portile2 (2.4.0)
     minitest (5.11.3)
     msgpack (1.2.4)
     multi_json (1.13.1)
@@ -345,26 +352,26 @@ GEM
     net-ldap (0.16.1)
     net-scp (1.2.1)
       net-ssh (>= 2.6.5)
-    net-ssh (4.2.0)
-    nio4r (2.3.0)
-    nokogiri (1.8.2)
-      mini_portile2 (~> 2.3.0)
-    nokogumbo (1.5.0)
-      nokogiri
-    nsa (0.2.4)
+    net-ssh (5.0.2)
+    nio4r (2.3.1)
+    nokogiri (1.10.1)
+      mini_portile2 (~> 2.4.0)
+    nokogumbo (2.0.0)
+      nokogiri (~> 1.8, >= 1.8.4)
+    nsa (0.2.7)
       activesupport (>= 4.2, < 6)
-      concurrent-ruby (~> 1.0.0)
-      sidekiq (>= 3.5.0)
-      statsd-ruby (~> 1.2.0)
-    oj (3.5.1)
-    omniauth (1.8.1)
-      hashie (>= 3.4.6, < 3.6.0)
+      concurrent-ruby (~> 1.0, >= 1.0.2)
+      sidekiq (>= 3.5)
+      statsd-ruby (~> 1.4, >= 1.4.0)
+    oj (3.7.7)
+    omniauth (1.9.0)
+      hashie (>= 3.4.6, < 3.7.0)
       rack (>= 1.6.2, < 3)
     omniauth-cas (1.1.1)
       addressable (~> 2.3)
       nokogiri (~> 1.5)
       omniauth (~> 1.2)
-    omniauth-saml (1.10.0)
+    omniauth-saml (1.10.1)
       omniauth (~> 1.3, >= 1.3.2)
       ruby-saml (~> 1.7)
     orm_adapter (0.5.0)
@@ -372,7 +379,7 @@ GEM
       addressable (~> 2.5)
       http (~> 3.0)
       nokogiri (~> 1.8)
-    ox (2.9.2)
+    ox (2.10.0)
     paperclip (6.0.0)
       activemodel (>= 4.2.0)
       activesupport (>= 4.2.0)
@@ -383,18 +390,18 @@ GEM
       av (~> 0.9.0)
       paperclip (>= 2.5.2)
     parallel (1.12.1)
-    parallel_tests (2.21.3)
+    parallel_tests (2.27.1)
       parallel
-    parser (2.5.1.0)
+    parser (2.6.0.0)
       ast (~> 2.4.0)
     pastel (0.7.2)
       equatable (~> 0.5.0)
       tty-color (~> 0.4.0)
-    pg (1.0.0)
-    pghero (2.1.0)
+    pg (1.1.4)
+    pghero (2.2.0)
       activerecord
-    pkg-config (1.3.0)
-    powerpack (0.1.1)
+    pkg-config (1.3.2)
+    powerpack (0.1.2)
     premailer (1.11.1)
       addressable
       css_parser (>= 1.6.0)
@@ -402,73 +409,74 @@ GEM
     premailer-rails (1.10.2)
       actionmailer (>= 3, < 6)
       premailer (~> 1.7, >= 1.7.9)
-    private_address_check (0.4.1)
-    pry (0.11.3)
+    private_address_check (0.5.0)
+    pry (0.12.2)
       coderay (~> 1.1.0)
       method_source (~> 0.9.0)
     pry-byebug (3.6.0)
       byebug (~> 10.0)
       pry (~> 0.10)
-    pry-rails (0.3.6)
+    pry-rails (0.3.9)
       pry (>= 0.10.4)
-    public_suffix (3.0.2)
-    puma (3.11.4)
-    pundit (1.1.0)
+    public_suffix (3.0.3)
+    puma (3.12.0)
+    pundit (2.0.0)
       activesupport (>= 3.0.0)
-    rack (2.0.4)
-    rack-attack (5.2.0)
-      rack
+    raabro (1.1.6)
+    rack (2.0.6)
+    rack-attack (5.4.2)
+      rack (>= 1.0, < 3)
     rack-cors (1.0.2)
-    rack-protection (2.0.1)
+    rack-protection (2.0.5)
       rack
     rack-proxy (0.6.4)
       rack
-    rack-test (1.0.0)
+    rack-test (1.1.0)
       rack (>= 1.0, < 3)
-    rails (5.2.0)
-      actioncable (= 5.2.0)
-      actionmailer (= 5.2.0)
-      actionpack (= 5.2.0)
-      actionview (= 5.2.0)
-      activejob (= 5.2.0)
-      activemodel (= 5.2.0)
-      activerecord (= 5.2.0)
-      activestorage (= 5.2.0)
-      activesupport (= 5.2.0)
+    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)
       bundler (>= 1.3.0)
-      railties (= 5.2.0)
+      railties (= 5.2.2)
       sprockets-rails (>= 2.0.0)
-    rails-controller-testing (1.0.2)
-      actionpack (~> 5.x, >= 5.0.1)
-      actionview (~> 5.x, >= 5.0.1)
-      activesupport (~> 5.x)
+    rails-controller-testing (1.0.4)
+      actionpack (>= 5.0.1.x)
+      actionview (>= 5.0.1.x)
+      activesupport (>= 5.0.1.x)
     rails-dom-testing (2.0.3)
       activesupport (>= 4.2.0)
       nokogiri (>= 1.6)
     rails-html-sanitizer (1.0.4)
       loofah (~> 2.2, >= 2.2.2)
-    rails-i18n (5.1.1)
+    rails-i18n (5.1.2)
       i18n (>= 0.7, < 2)
       railties (>= 5.0, < 6)
     rails-settings-cached (0.6.6)
       rails (>= 4.2.0)
-    railties (5.2.0)
-      actionpack (= 5.2.0)
-      activesupport (= 5.2.0)
+    railties (5.2.2)
+      actionpack (= 5.2.2)
+      activesupport (= 5.2.2)
       method_source
       rake (>= 0.8.7)
-      thor (>= 0.18.1, < 2.0)
+      thor (>= 0.19.0, < 2.0)
     rainbow (3.0.0)
-    rake (12.3.1)
+    rake (12.3.2)
     rb-fsevent (0.10.3)
     rb-inotify (0.9.10)
       ffi (>= 0.5.0, < 2)
-    rdf (3.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.0.1)
+    redis (4.1.0)
     redis-actionpack (5.0.2)
       actionpack (>= 4.0, < 6)
       redis-rack (>= 1, < 3)
@@ -487,6 +495,7 @@ GEM
       redis-store (>= 1.2, < 2)
     redis-store (1.5.0)
       redis (>= 2.2, < 5)
+    regexp_parser (1.3.0)
     request_store (1.4.1)
       rack (>= 1.4)
     responders (2.4.0)
@@ -496,72 +505,73 @@ GEM
     rpam2 (4.0.2)
     rqrcode (0.10.1)
       chunky_png (~> 1.0)
-    rspec-core (3.7.1)
-      rspec-support (~> 3.7.0)
-    rspec-expectations (3.7.0)
+    rspec-core (3.8.0)
+      rspec-support (~> 3.8.0)
+    rspec-expectations (3.8.2)
       diff-lcs (>= 1.2.0, < 2.0)
-      rspec-support (~> 3.7.0)
-    rspec-mocks (3.7.0)
+      rspec-support (~> 3.8.0)
+    rspec-mocks (3.8.0)
       diff-lcs (>= 1.2.0, < 2.0)
-      rspec-support (~> 3.7.0)
-    rspec-rails (3.7.2)
+      rspec-support (~> 3.8.0)
+    rspec-rails (3.8.1)
       actionpack (>= 3.0)
       activesupport (>= 3.0)
       railties (>= 3.0)
-      rspec-core (~> 3.7.0)
-      rspec-expectations (~> 3.7.0)
-      rspec-mocks (~> 3.7.0)
-      rspec-support (~> 3.7.0)
+      rspec-core (~> 3.8.0)
+      rspec-expectations (~> 3.8.0)
+      rspec-mocks (~> 3.8.0)
+      rspec-support (~> 3.8.0)
     rspec-sidekiq (3.0.3)
       rspec-core (~> 3.0, >= 3.0.0)
       sidekiq (>= 2.4.0)
-    rspec-support (3.7.1)
-    rubocop (0.55.0)
+    rspec-support (3.8.0)
+    rubocop (0.63.0)
+      jaro_winkler (~> 1.5.1)
       parallel (~> 1.10)
-      parser (>= 2.5)
+      parser (>= 2.5, != 2.5.1.1)
       powerpack (~> 0.1)
       rainbow (>= 2.2.2, < 4.0)
       ruby-progressbar (~> 1.7)
-      unicode-display_width (~> 1.0, >= 1.0.1)
-    ruby-progressbar (1.9.0)
-    ruby-saml (1.7.2)
+      unicode-display_width (~> 1.4.0)
+    ruby-progressbar (1.10.0)
+    ruby-saml (1.9.0)
       nokogiri (>= 1.5.10)
-    rufus-scheduler (3.4.2)
-      et-orbi (~> 1.0)
+    rufus-scheduler (3.5.2)
+      fugit (~> 1.1, >= 1.1.5)
     safe_yaml (1.0.4)
-    sanitize (4.6.4)
+    sanitize (5.0.0)
       crass (~> 1.0.2)
-      nokogiri (>= 1.4.4)
-      nokogumbo (~> 1.4)
-    sass (3.5.6)
+      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.0)
+    scss_lint (0.57.1)
       rake (>= 0.9, < 13)
-      sass (~> 3.5.5)
-    sidekiq (5.1.3)
-      concurrent-ruby (~> 1.0)
-      connection_pool (~> 2.2, >= 2.2.0)
+      sass (~> 3.5, >= 3.5.5)
+    sidekiq (5.2.5)
+      connection_pool (~> 2.2, >= 2.2.2)
+      rack (>= 1.5.0)
       rack-protection (>= 1.5.0)
       redis (>= 3.3.5, < 5)
-    sidekiq-bulk (0.1.1)
-      activesupport
+    sidekiq-bulk (0.2.0)
       sidekiq
-    sidekiq-scheduler (2.2.1)
+    sidekiq-scheduler (3.0.0)
       redis (>= 3, < 5)
       rufus-scheduler (~> 3.2)
       sidekiq (>= 3)
       tilt (>= 1.4.0)
-    sidekiq-unique-jobs (5.0.10)
-      sidekiq (>= 4.0, <= 6.0)
+    sidekiq-unique-jobs (6.0.8)
+      concurrent-ruby (~> 1.0, >= 1.0.5)
+      sidekiq (>= 4.0, < 6.0)
       thor (~> 0)
     simple-navigation (4.0.5)
       activesupport (>= 2.3.2)
-    simple_form (4.0.0)
-      actionpack (> 4)
-      activemodel (> 4)
+    simple_form (4.1.0)
+      actionpack (>= 5.0)
+      activemodel (>= 5.0)
     simplecov (0.16.1)
       docile (~> 1.1)
       json (>= 1.8, < 3)
@@ -574,71 +584,69 @@ GEM
       actionpack (>= 4.0)
       activesupport (>= 4.0)
       sprockets (>= 3.0.0)
-    sshkit (1.16.0)
+    sshkit (1.17.0)
       net-scp (>= 1.1.2)
       net-ssh (>= 2.8.0)
-    stackprof (0.2.11)
-    statsd-ruby (1.2.1)
+    stackprof (0.2.12)
+    statsd-ruby (1.4.0)
     stoplight (2.1.3)
     streamio-ffmpeg (3.0.2)
       multi_json (~> 1.8)
-    strong_migrations (0.2.2)
+    strong_migrations (0.3.1)
       activerecord (>= 3.2.0)
     temple (0.8.0)
     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.0)
-    thread (0.2.2)
+    thor (0.20.3)
     thread_safe (0.3.6)
     tilt (2.0.8)
-    timers (4.1.2)
-      hitimes
-    tty-color (0.4.2)
-    tty-command (0.8.0)
+    timers (4.2.0)
+    tty-color (0.4.3)
+    tty-command (0.8.2)
       pastel (~> 0.7.0)
-    tty-cursor (0.5.0)
-    tty-prompt (0.16.0)
+    tty-cursor (0.6.0)
+    tty-prompt (0.18.1)
       necromancer (~> 0.4.0)
       pastel (~> 0.7.0)
       timers (~> 4.0)
-      tty-cursor (~> 0.5.0)
-      tty-reader (~> 0.2.0)
-    tty-reader (0.2.0)
-      tty-cursor (~> 0.5.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)
       wisper (~> 2.0.0)
-    tty-screen (0.6.4)
+    tty-screen (0.6.5)
     twitter-text (1.14.7)
       unf (~> 0.1.0)
     tzinfo (1.2.5)
       thread_safe (~> 0.1)
-    tzinfo-data (1.2018.4)
+    tzinfo-data (1.2018.9)
       tzinfo (>= 1.0.0)
     unf (0.1.4)
       unf_ext
     unf_ext (0.0.7.5)
-    unicode-display_width (1.3.2)
-    uniform_notifier (1.11.0)
+    unicode-display_width (1.4.1)
+    uniform_notifier (1.12.1)
     warden (1.2.7)
       rack (>= 1.0)
-    webmock (3.3.0)
+    webmock (3.5.1)
       addressable (>= 2.3.6)
       crack (>= 0.3.2)
       hashdiff
-    webpacker (3.4.3)
+    webpacker (3.5.5)
       activesupport (>= 4.2)
       rack-proxy (>= 0.6.1)
       railties (>= 4.2)
-    webpush (0.3.3)
+    webpush (0.3.6)
       hkdf (~> 0.2)
       jwt (~> 2.0)
     websocket-driver (0.7.0)
       websocket-extensions (>= 0.1.0)
     websocket-extensions (0.1.3)
     wisper (2.0.0)
-    xpath (3.0.0)
+    xpath (3.2.0)
       nokogiri (~> 1.8)
 
 PLATFORMS
@@ -649,119 +657,121 @@ DEPENDENCIES
   active_record_query_trace (~> 1.5)
   addressable (~> 2.5)
   annotate (~> 2.7)
-  aws-sdk-s3 (~> 1.9)
-  better_errors (~> 2.4)
+  aws-sdk-s3 (~> 1.30)
+  better_errors (~> 2.5)
   binding_of_caller (~> 0.7)
   bootsnap (~> 1.3)
-  brakeman (~> 4.2)
+  brakeman (~> 4.4)
   browser
-  bullet (~> 5.7)
+  bullet (~> 5.9)
   bundler-audit (~> 0.6)
-  capistrano (~> 3.10)
-  capistrano-rails (~> 1.3)
+  capistrano (~> 3.11)
+  capistrano-rails (~> 1.4)
   capistrano-rbenv (~> 2.1)
   capistrano-yarn (~> 2.0)
-  capybara (~> 2.18)
+  capybara (~> 3.12)
   charlock_holmes (~> 0.7.6)
   chewy (~> 5.0)
-  cld3 (~> 3.2.0)
+  cld3 (~> 3.2.3)
   climate_control (~> 0.2)
+  concurrent-ruby
   derailed_benchmarks
-  devise (~> 4.4)
+  devise (~> 4.5)
   devise-two-factor (~> 3.0)
-  devise_pam_authenticatable2 (~> 9.1)
-  doorkeeper (~> 4.2, < 4.3)
-  dotenv-rails (~> 2.2, < 2.3)
+  devise_pam_authenticatable2 (~> 9.2)
+  doorkeeper (~> 5.0)
+  dotenv-rails (~> 2.6)
   fabrication (~> 2.20)
-  faker (~> 1.8)
+  faker (~> 1.9)
   fast_blank (~> 1.0)
   fastimage
-  fog-core (~> 1.45)
-  fog-local (~> 0.5)
-  fog-openstack (~> 0.1)
-  fuubar (~> 2.2)
+  fog-core (<= 2.1.0)
+  fog-openstack (~> 0.3)
+  fuubar (~> 2.3)
   goldfinger (~> 2.1)
   hamlit-rails (~> 0.2)
   hiredis (~> 0.6)
   htmlentities (~> 4.3)
-  http (~> 3.2)
+  http (~> 3.3)
   http_accept_language (~> 2.1)
   http_parser.rb (~> 0.6)!
-  httplog (~> 1.0)
+  httplog (~> 1.2)
   i18n-tasks (~> 0.9)
   idn-ruby
   iso-639
-  json-ld (~> 2.2)
+  json-ld (~> 3.0)
+  json-ld-preloaded (~> 3.0)
   kaminari (~> 1.1)
-  letter_opener (~> 1.4)
+  letter_opener (~> 1.7)
   letter_opener_web (~> 1.3)
   link_header (~> 0.0)
   lograge (~> 0.10)
+  makara (~> 0.4)
   mario-redis-lock (~> 1.2)
   memory_profiler
   microformats (~> 4.0)
-  mime-types (~> 3.1)
+  mime-types (~> 3.2)
   net-ldap (~> 0.10)
-  nokogiri (~> 1.8)
+  nokogiri (~> 1.10)
   nsa (~> 0.2)
-  oj (~> 3.5)
-  omniauth (~> 1.2)
+  oj (~> 3.7)
+  omniauth (~> 1.9)
   omniauth-cas (~> 1.1)
   omniauth-saml (~> 1.10)
   ostatus2 (~> 2.0)
-  ox (~> 2.9)
+  ox (~> 2.10)
   paperclip (~> 6.0)
   paperclip-av-transcoder (~> 0.6)
-  parallel_tests (~> 2.21)
-  pg (~> 1.0)
-  pghero (~> 2.1)
+  parallel_tests (~> 2.27)
+  pg (~> 1.1)
+  pghero (~> 2.2)
   pkg-config (~> 1.3)
   posix-spawn!
   premailer-rails
-  private_address_check (~> 0.4.1)
+  private_address_check (~> 0.5)
   pry-byebug (~> 3.6)
   pry-rails (~> 0.3)
-  puma (~> 3.11)
-  pundit (~> 1.1)
-  rack-attack (~> 5.2)
+  puma (~> 3.12)
+  pundit (~> 2.0)
+  rack-attack (~> 5.4)
   rack-cors (~> 1.0)
-  rails (~> 5.2.0)
+  rails (~> 5.2.2)
   rails-controller-testing (~> 1.0)
   rails-i18n (~> 5.1)
   rails-settings-cached (~> 0.6)
   rdf-normalize (~> 0.3)
-  redis (~> 4.0)
+  redis (~> 4.1)
   redis-namespace (~> 1.5)
   redis-rails (~> 5.0)
   rqrcode (~> 0.10)
-  rspec-rails (~> 3.7)
+  rspec-rails (~> 3.8)
   rspec-sidekiq (~> 3.0)
-  rubocop (~> 0.55)
-  ruby-progressbar (~> 1.4)
-  sanitize (~> 4.6)
+  rubocop (~> 0.63)
+  sanitize (~> 5.0)
   scss_lint (~> 0.57)
-  sidekiq (~> 5.1)
-  sidekiq-bulk (~> 0.1.1)
-  sidekiq-scheduler (~> 2.2)
-  sidekiq-unique-jobs (~> 5.0)
+  sidekiq (~> 5.2)
+  sidekiq-bulk (~> 0.2.0)
+  sidekiq-scheduler (~> 3.0)
+  sidekiq-unique-jobs (~> 6.0)
   simple-navigation (~> 4.0)
-  simple_form (~> 4.0)
+  simple_form (~> 4.1)
   simplecov (~> 0.16)
   sprockets-rails (~> 3.2)
   stackprof
   stoplight (~> 2.1.3)
   streamio-ffmpeg (~> 3.0)
-  strong_migrations (~> 0.2)
+  strong_migrations (~> 0.3)
+  thor (~> 0.20)
   tty-command (~> 0.8)
-  tty-prompt (~> 0.16)
+  tty-prompt (~> 0.18)
   twitter-text (~> 1.14)
   tzinfo-data (~> 1.2018)
-  webmock (~> 3.3)
-  webpacker (~> 3.4)
+  webmock (~> 3.5)
+  webpacker (~> 3.5)
   webpush
 
 RUBY VERSION
-   ruby 2.5.0p0
+   ruby 2.6.0p0
 
 BUNDLED WITH
-   1.16.2
+   1.17.3
diff --git a/README.md b/README.md
index 458946f2cc28f84200f57a92c41c83a5336d4f61..6c4918e6f237bd78590a3703827e307cce647457 100644
--- a/README.md
+++ b/README.md
@@ -1,96 +1,95 @@
 ![Mastodon](https://i.imgur.com/NhZc40l.png)
 ========
 
+[![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]
+[![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/
+[docker]: https://hub.docker.com/r/tootsuite/mastodon/
 
-Mastodon is a **free, open-source social network server** based on **open web protocols** like ActivityPub and OStatus. The social focus of the project is a viable decentralized alternative to commercial social media silos that returns the control of the content distribution channels to the people. The technical focus of the project is a good user interface, a clean REST API for 3rd party apps and robust anti-abuse tools.
+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!
 
-Click on the screenshot below to watch a demo of the UI:
+Click below to **learn more** in a video:
 
-[![Screenshot](https://i.imgur.com/qrNOiSp.png)][youtube_demo]
+[![Screenshot](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/ezgif-2-60f1b00403.gif)][youtube_demo]
 
 [youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE
 
-**Ruby on Rails** is used for the back-end, while **React.js** and Redux are used for the dynamic front-end. A static front-end for public resources (profiles and statuses) is also provided.
+## Navigation 
 
-If you would like, you can [support the development of this project on Patreon][patreon] or [Liberapay][liberapay].
+- [Project homepage 🐘](https://joinmastodon.org)
+- [Support the development via Patreon][patreon]
+- [View sponsors](https://joinmastodon.org/sponsors)
+- [Blog](https://blog.joinmastodon.org)
+- [Documentation](https://docs.joinmastodon.org)
+- [Browse Mastodon servers](https://joinmastodon.org/#getting-started)
+- [Browse Mastodon apps](https://joinmastodon.org/apps)
 
-[patreon]: https://www.patreon.com/user?u=619786
-[liberapay]: https://liberapay.com/Mastodon/
-
----
-
-## Resources
-
-- [Frequently Asked Questions](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/FAQ.md)
-- [Use this tool to find Twitter friends on Mastodon](https://bridge.joinmastodon.org)
-- [API overview](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md)
-- [List of Mastodon instances](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/List-of-Mastodon-instances.md)
-- [List of apps](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md)
-- [List of sponsors](https://joinmastodon.org/sponsors)
+[patreon]: https://www.patreon.com/mastodon
 
 ## Features
 
+<img src="https://docs.joinmastodon.org/elephant.svg" align="right" width="30%" />
+
 **No vendor lock-in: Fully interoperable with any conforming platform**
 
-It doesn't have to be Mastodon, whatever implements ActivityPub or OStatus is part of the social network!
+It doesn't have to be Mastodon, whatever implements ActivityPub is part of the social network! [Learn more](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/)
 
-**Real-time timeline updates**
+**Real-time, chronological timeline updates**
 
 See the updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well!
 
-**Federated thread resolving**
-
-If someone you follow replies to a user unknown to the server, the server fetches the full thread so you can view it without leaving the UI
-
 **Media attachments like images and short videos**
 
 Upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos are looped - like vines!
 
-**OAuth2 and a straightforward REST API**
+**Safety and moderation tools**
 
-Mastodon acts as an OAuth2 provider so 3rd party apps can use the API
+Private posts, locked accounts, phrase filtering, muting, blocking and all sorts of other features, along with a reporting and moderation system. [Learn more](https://blog.joinmastodon.org/2018/07/cage-the-mastodon/)
 
-**Fast response times**
+**OAuth2 and a straightforward REST API**
 
-Mastodon tries to be as fast and responsive as possible, so all long-running tasks are delegated to background processing
+Mastodon acts as an OAuth2 provider so 3rd party apps can use the REST and Streaming APIs, resulting in a rich app ecosystem with a lot of choice!
 
-**Deployable via Docker**
+## Deployment
 
-You don't need to mess with dependencies and configuration if you want to try Mastodon, if you have Docker and Docker Compose the deployment is extremely easy
+**Tech stack:**
 
----
+- **Ruby on Rails** powers the REST API and other web pages
+- **React.js** and Redux are used for the dynamic parts of the interface
+- **Node.js** powers the streaming API
 
-## Development
+**Requirements:**
 
-Please follow the [development guide](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Development-guide.md) from the documentation repository.
+- **PostgreSQL** 9.5+
+- **Redis**
+- **Ruby** 2.4+
+- **Node.js** 8+
 
-## Deployment
+The repository includes deployment configurations for **Docker and docker-compose**, but also a few specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. The [**stand-alone** installation guide](https://docs.joinmastodon.org/administration/installation/) is available in the documentation.
 
-There are guides in the documentation repository for [deploying on various platforms](https://github.com/tootsuite/documentation#running-mastodon).
+A **Vagrant** configuration is included for development purposes.
 
 ## Contributing
 
-You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository. [Here are the guidelines for code contributions](CONTRIBUTING.md)
+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)
 
 **IRC channel**: #mastodon on irc.freenode.net
 
 ## License
 
-Copyright (C) 2016-2018 Eugen Rochko & other Mastodon contributors (see AUTHORS.md)
+Copyright (C) 2016-2018 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.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
 
 You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
-
----
-
-## Extra credits
-
-The elephant friend illustrations are created by [Dopatwo](https://mastodon.social/@dopatwo)
diff --git a/Vagrantfile b/Vagrantfile
index ddcdf3510240441abd3408c0046b7df8a590962a..f9839fffb9cb3cc392d059743327df8ee08edadf 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -12,7 +12,7 @@ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
 sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
 
 # Add repo for NodeJS
-curl -sL https://deb.nodesource.com/setup_6.x | sudo bash -
+curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
 
 # Add firewall rule to redirect 80 to PORT and save
 sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
@@ -44,7 +44,7 @@ sudo apt-get install \
 
 # Install rvm
 read RUBY_VERSION < .ruby-version
-gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
+gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
 curl -sSL https://raw.githubusercontent.com/rvm/rvm/stable/binscripts/rvm-installer | bash -s stable --ruby=$RUBY_VERSION
 source /home/vagrant/.rvm/scripts/rvm
 
@@ -85,6 +85,9 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
   config.vm.provider :virtualbox do |vb|
     vb.name = "mastodon"
     vb.customize ["modifyvm", :id, "--memory", "2048"]
+    # Increase the number of CPUs. Uncomment and adjust to
+    # increase performance
+    # vb.customize ["modifyvm", :id, "--cpus", "3"]
 
     # Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
     # https://github.com/mitchellh/vagrant/issues/1172
@@ -97,19 +100,22 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
 
   end
 
-  config.vm.hostname = "mastodon.dev"
-
   # This uses the vagrant-hostsupdater plugin, and lets you
-  # access the development site at http://mastodon.dev.
+  # access the development site at http://mastodon.local.
+  # If you change it, also change it in .env.vagrant before provisioning
+  # the vagrant server to update the development build.
+  #
   # To install:
   #   $ vagrant plugin install vagrant-hostsupdater
+  config.vm.hostname = "mastodon.local"
+
   if defined?(VagrantPlugins::HostsUpdater)
     config.vm.network :private_network, ip: "192.168.42.42", nictype: "virtio"
     config.hostsupdater.remove_on_suspend = false
   end
 
   if config.vm.networks.any? { |type, options| type == :private_network }
-    config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'vers=3', 'tcp']
+    config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'vers=3', 'tcp', 'actimeo=1']
   else
     config.vm.synced_folder ".", "/vagrant"
   end
diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb
index 8bf5b4af7cf52cb9a35f3106756f9b88f08f6707..d3104172c485d1d7b3feaf006857993425bd27c6 100644
--- a/app/chewy/statuses_index.rb
+++ b/app/chewy/statuses_index.rb
@@ -31,7 +31,7 @@ class StatusesIndex < Chewy::Index
     },
   }
 
-  define_type ::Status.without_reblogs do
+  define_type ::Status.unscoped.without_reblogs 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) }
diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb
index 4ffdfb6856c3d43a03774c9dcf6823e1db10a4c9..0dbf0283d206e8959c2fbdfaab78835128deedfb 100644
--- a/app/controllers/about_controller.rb
+++ b/app/controllers/about_controller.rb
@@ -9,9 +9,13 @@ class AboutController < ApplicationController
     @initial_state_json   = serializable_resource.to_json
   end
 
-  def more; end
+  def more
+    render layout: 'public'
+  end
 
-  def terms; end
+  def terms
+    render layout: 'public'
+  end
 
   private
 
@@ -26,7 +30,7 @@ class AboutController < ApplicationController
   end
 
   def set_body_classes
-    @body_classes = 'about-body'
+    @body_classes = 'with-modals'
   end
 
   def initial_state_params
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index 1152d4aca57e334de6f3321474058a35d4e65663..f788a907893059ca3abad0e94745115863d9495f 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -10,7 +10,9 @@ class AccountsController < ApplicationController
   def show
     respond_to do |format|
       format.html do
-        @pinned_statuses = []
+        @body_classes      = 'with-modals'
+        @pinned_statuses   = []
+        @endorsed_accounts = @account.endorsed_accounts.to_a.sample(4)
 
         if current_account && @account.blocking?(current_account)
           @statuses = []
@@ -40,7 +42,7 @@ class AccountsController < ApplicationController
       format.json do
         skip_session!
 
-        render_cached_json(['activitypub', 'actor', @account.cache_key], content_type: 'application/activity+json') do
+        render_cached_json(['activitypub', 'actor', @account], content_type: 'application/activity+json') do
           ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter)
         end
       end
@@ -50,7 +52,7 @@ class AccountsController < ApplicationController
   private
 
   def show_pinned_statuses?
-    [replies_requested?, media_requested?, params[:max_id].present?, params[:since_id].present?].none?
+    [replies_requested?, media_requested?, params[:max_id].present?, params[:min_id].present?].none?
   end
 
   def filtered_statuses
diff --git a/app/controllers/activitypub/collections_controller.rb b/app/controllers/activitypub/collections_controller.rb
index 96bf901a7cc14251707498c679cdc73ec98f9bb5..995da9c55dc0858f814d56f584c27e8a9274003c 100644
--- a/app/controllers/activitypub/collections_controller.rb
+++ b/app/controllers/activitypub/collections_controller.rb
@@ -31,7 +31,7 @@ class ActivityPub::CollectionsController < Api::BaseController
     when 'featured'
       @account.pinned_statuses.count
     else
-      raise ActiveRecord::NotFound
+      raise ActiveRecord::RecordNotFound
     end
   end
 
@@ -42,7 +42,7 @@ class ActivityPub::CollectionsController < Api::BaseController
         scope.merge!(@account.pinned_statuses)
       end
     else
-      raise ActiveRecord::NotFound
+      raise ActiveRecord::RecordNotFound
     end
   end
 
diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb
index af51e32d5d31148512b655a9a225340babe40e6a..8f5e1887ea427525bb72bca04d1405d756978d57 100644
--- a/app/controllers/activitypub/inboxes_controller.rb
+++ b/app/controllers/activitypub/inboxes_controller.rb
@@ -36,6 +36,6 @@ class ActivityPub::InboxesController < Api::BaseController
   end
 
   def process_payload
-    ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body.force_encoding('UTF-8'))
+    ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body.force_encoding('UTF-8'), @account&.id)
   end
 end
diff --git a/app/controllers/admin/account_actions_controller.rb b/app/controllers/admin/account_actions_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a2cea461ee1950e2c971e3455378380407221a50
--- /dev/null
+++ b/app/controllers/admin/account_actions_controller.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Admin
+  class AccountActionsController < BaseController
+    before_action :set_account
+
+    def new
+      @account_action  = Admin::AccountAction.new(type: params[:type], report_id: params[:report_id], send_email_notification: true)
+      @warning_presets = AccountWarningPreset.all
+    end
+
+    def create
+      account_action                 = Admin::AccountAction.new(resource_params)
+      account_action.target_account  = @account
+      account_action.current_account = current_account
+
+      account_action.save!
+
+      if account_action.with_report?
+        redirect_to admin_reports_path
+      else
+        redirect_to admin_account_path(@account.id)
+      end
+    end
+
+    private
+
+    def set_account
+      @account = Account.find(params[:account_id])
+    end
+
+    def resource_params
+      params.require(:admin_account_action).permit(:type, :report_id, :warning_preset_id, :text, :send_email_notification)
+    end
+  end
+end
diff --git a/app/controllers/admin/account_moderation_notes_controller.rb b/app/controllers/admin/account_moderation_notes_controller.rb
index 7d5b9bf52c83f633404267b4d035180a6600c545..44f6e34f80b0ad4f30d6dba37969320d4d842851 100644
--- a/app/controllers/admin/account_moderation_notes_controller.rb
+++ b/app/controllers/admin/account_moderation_notes_controller.rb
@@ -14,6 +14,7 @@ module Admin
       else
         @account          = @account_moderation_note.target_account
         @moderation_notes = @account.targeted_moderation_notes.latest
+        @warnings         = @account.targeted_account_warnings.latest.custom
 
         render template: 'admin/accounts/show'
       end
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb
index e7ca6b9074ab725fb89c1f7de801cb52035238dc..562fba9960dd21d8e9ceeb7cee72302a847bf8a7 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, :enable, :disable, :memorialize]
+    before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :unsilence, :unsuspend, :memorialize]
     before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
-    before_action :require_local_account!, only: [:enable, :disable, :memorialize]
+    before_action :require_local_account!, only: [:enable, :memorialize]
 
     def index
       authorize :account, :index?
@@ -13,8 +13,10 @@ module Admin
 
     def show
       authorize @account, :show?
+
       @account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
-      @moderation_notes = @account.targeted_moderation_notes.latest
+      @moderation_notes        = @account.targeted_moderation_notes.latest
+      @warnings                = @account.targeted_account_warnings.latest.custom
     end
 
     def subscribe
@@ -43,19 +45,25 @@ module Admin
       redirect_to admin_account_path(@account.id)
     end
 
-    def disable
-      authorize @account.user, :disable?
-      @account.user.disable!
-      log_action :disable, @account.user
+    def unsilence
+      authorize @account, :unsilence?
+      @account.unsilence!
+      log_action :unsilence, @account
+      redirect_to admin_account_path(@account.id)
+    end
+
+    def unsuspend
+      authorize @account, :unsuspend?
+      @account.unsuspend!
+      log_action :unsuspend, @account
       redirect_to admin_account_path(@account.id)
     end
 
     def redownload
       authorize @account, :redownload?
 
-      @account.reset_avatar!
-      @account.reset_header!
-      @account.save!
+      @account.update!(last_webfingered_at: nil)
+      ResolveAccountService.new.call(@account)
 
       redirect_to admin_account_path(@account.id)
     end
@@ -71,6 +79,17 @@ module Admin
       redirect_to admin_account_path(@account.id)
     end
 
+    def remove_header
+      authorize @account, :remove_header?
+
+      @account.header = nil
+      @account.save!
+
+      log_action :remove_header, @account.user
+
+      redirect_to admin_account_path(@account.id)
+    end
+
     private
 
     def set_account
@@ -94,8 +113,8 @@ module Admin
         :local,
         :remote,
         :by_domain,
+        :active,
         :silenced,
-        :recent,
         :suspended,
         :username,
         :display_name,
diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb
index 7fb69d5789ec855b487d08284f2a2e6122d98371..7b81a2b01d1b4a7b52cb4e32d74c4a9222282446 100644
--- a/app/controllers/admin/base_controller.rb
+++ b/app/controllers/admin/base_controller.rb
@@ -5,8 +5,19 @@ module Admin
     include Authorization
     include AccountableConcern
 
+    layout 'admin'
+
     before_action :require_staff!
+    before_action :set_body_classes
 
-    layout 'admin'
+    private
+
+    def set_body_classes
+      @body_classes = 'admin'
+    end
+
+    def set_user
+      @user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
+    end
   end
 end
diff --git a/app/controllers/admin/confirmations_controller.rb b/app/controllers/admin/confirmations_controller.rb
index 8d3477e660256c58e39f60f31f4cb0544d3b9c2a..efe7dcbd4b3a408d94732ba30244e00d666109ea 100644
--- a/app/controllers/admin/confirmations_controller.rb
+++ b/app/controllers/admin/confirmations_controller.rb
@@ -25,10 +25,6 @@ module Admin
 
     private
 
-    def set_user
-      @user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
-    end
-
     def check_confirmation
       if @user.confirmed?
         flash[:error] = I18n.t('admin.accounts.resend_confirmation.already_confirmed')
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bb923c18594c78fee477a00eee9238466e715a4e
--- /dev/null
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+require 'sidekiq/api'
+
+module Admin
+  class DashboardController < BaseController
+    def index
+      @users_count           = User.count
+      @registrations_week    = Redis.current.get("activity:accounts:local:#{current_week}") || 0
+      @logins_week           = Redis.current.pfcount("activity:logins:#{current_week}")
+      @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
+      @deletions_enabled     = Setting.open_deletion
+      @invites_enabled       = Setting.min_invite_role == 'user'
+      @search_enabled        = Chewy.enabled?
+      @version               = Mastodon::Version.to_s
+      @database_version      = ActiveRecord::Base.connection.execute('SELECT VERSION()').first['version'].match(/\A(?:PostgreSQL |)([^\s]+).*\z/)[1]
+      @redis_version         = redis_info['redis_version']
+      @reports_count         = Report.unresolved.count
+      @queue_backlog         = Sidekiq::Stats.new.enqueued
+      @recent_users          = User.confirmed.recent.includes(:account).limit(4)
+      @database_size         = ActiveRecord::Base.connection.execute('SELECT pg_database_size(current_database())').first['pg_database_size']
+      @redis_size            = redis_info['used_memory']
+      @ldap_enabled          = ENV['LDAP_ENABLED'] == 'true'
+      @cas_enabled           = ENV['CAS_ENABLED'] == 'true'
+      @saml_enabled          = ENV['SAML_ENABLED'] == 'true'
+      @pam_enabled           = ENV['PAM_ENABLED'] == 'true'
+      @hidden_service        = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true'
+      @trending_hashtags     = TrendingTags.get(7)
+      @profile_directory     = Setting.profile_directory
+    end
+
+    private
+
+    def current_week
+      @current_week ||= Time.now.utc.to_date.cweek
+    end
+
+    def redis_info
+      @redis_info ||= Redis.current.info
+    end
+  end
+end
diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb
index 64de2cbf0cfd0998d52c420072533b9ab10a874a..5f307ddeeca04564e75a93c18bc64656c0f2dd79 100644
--- a/app/controllers/admin/domain_blocks_controller.rb
+++ b/app/controllers/admin/domain_blocks_controller.rb
@@ -4,14 +4,9 @@ module Admin
   class DomainBlocksController < BaseController
     before_action :set_domain_block, only: [:show, :destroy]
 
-    def index
-      authorize :domain_block, :index?
-      @domain_blocks = DomainBlock.page(params[:page])
-    end
-
     def new
       authorize :domain_block, :create?
-      @domain_block = DomainBlock.new
+      @domain_block = DomainBlock.new(domain: params[:_domain])
     end
 
     def create
@@ -22,7 +17,7 @@ module Admin
       if @domain_block.save
         DomainBlockWorker.perform_async(@domain_block.id)
         log_action :create, @domain_block
-        redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.created_msg')
+        redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
       else
         render :new
       end
@@ -36,7 +31,7 @@ module Admin
       authorize @domain_block, :destroy?
       UnblockDomainService.new.call(@domain_block, retroactive_unblock?)
       log_action :destroy, @domain_block
-      redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.destroyed_msg')
+      redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.destroyed_msg')
     end
 
     private
@@ -46,7 +41,7 @@ module Admin
     end
 
     def resource_params
-      params.require(:domain_block).permit(:domain, :severity, :reject_media, :retroactive)
+      params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :retroactive)
     end
 
     def retroactive_unblock?
diff --git a/app/controllers/admin/followers_controller.rb b/app/controllers/admin/followers_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d826f47c5ae81f752de8adf0d268379beeec227b
--- /dev/null
+++ b/app/controllers/admin/followers_controller.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Admin
+  class FollowersController < BaseController
+    before_action :set_account
+
+    PER_PAGE = 40
+
+    def index
+      authorize :account, :index?
+      @followers = @account.followers.local.recent.page(params[:page]).per(PER_PAGE)
+    end
+
+    def set_account
+      @account = Account.find(params[:account_id])
+    end
+  end
+end
diff --git a/app/controllers/admin/instances_controller.rb b/app/controllers/admin/instances_controller.rb
index 8ed0ea4219556f53767476d843849c53a11d505f..431ce6f4de1768696e2d0ff5880dd26711eb1844 100644
--- a/app/controllers/admin/instances_controller.rb
+++ b/app/controllers/admin/instances_controller.rb
@@ -4,14 +4,21 @@ module Admin
   class InstancesController < BaseController
     def index
       authorize :instance, :index?
+
       @instances = ordered_instances
     end
 
-    def resubscribe
-      authorize :instance, :resubscribe?
-      params.require(:by_domain)
-      Pubsubhubbub::SubscribeWorker.push_bulk(subscribeable_accounts.pluck(:id))
-      redirect_to admin_instances_path
+    def show
+      authorize :instance, :show?
+
+      @instance        = Instance.new(Account.by_domain_accounts.find_by(domain: params[:id]) || DomainBlock.find_by!(domain: params[:id]))
+      @following_count = Follow.where(account: Account.where(domain: params[:id])).count
+      @followers_count = Follow.where(target_account: Account.where(domain: params[:id])).count
+      @reports_count   = Report.where(target_account: Account.where(domain: params[:id])).count
+      @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])
     end
 
     private
@@ -27,17 +34,11 @@ module Admin
     helper_method :paginated_instances
 
     def ordered_instances
-      paginated_instances.map { |account| Instance.new(account) }
-    end
-
-    def subscribeable_accounts
-      Account.with_followers.remote.where(domain: params[:by_domain])
+      paginated_instances.map { |resource| Instance.new(resource) }
     end
 
     def filter_params
-      params.permit(
-        :domain_name
-      )
+      params.permit(:limited)
     end
   end
 end
diff --git a/app/controllers/admin/invites_controller.rb b/app/controllers/admin/invites_controller.rb
index faccaa7c899da1be4084738991b065a0233810af..44a8eec77b2eea27baf239b82797c5e87a2ef225 100644
--- a/app/controllers/admin/invites_controller.rb
+++ b/app/controllers/admin/invites_controller.rb
@@ -30,6 +30,12 @@ module Admin
       redirect_to admin_invites_path
     end
 
+    def deactivate_all
+      authorize :invite, :deactivate_all?
+      Invite.available.in_batches.update_all(expires_at: Time.now.utc)
+      redirect_to admin_invites_path
+    end
+
     private
 
     def resource_params
diff --git a/app/controllers/admin/relays_controller.rb b/app/controllers/admin/relays_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1b02d3c361a9e77c49c2fc40e2e15fdf52afc05c
--- /dev/null
+++ b/app/controllers/admin/relays_controller.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Admin
+  class RelaysController < BaseController
+    before_action :set_relay, except: [:index, :new, :create]
+
+    def index
+      authorize :relay, :update?
+      @relays = Relay.all
+    end
+
+    def new
+      authorize :relay, :update?
+      @relay = Relay.new(inbox_url: Relay::PRESET_RELAY)
+    end
+
+    def create
+      authorize :relay, :update?
+
+      @relay = Relay.new(resource_params)
+
+      if @relay.save
+        @relay.enable!
+        redirect_to admin_relays_path
+      else
+        render action: :new
+      end
+    end
+
+    def destroy
+      authorize :relay, :update?
+      @relay.destroy
+      redirect_to admin_relays_path
+    end
+
+    def enable
+      authorize :relay, :update?
+      @relay.enable!
+      redirect_to admin_relays_path
+    end
+
+    def disable
+      authorize :relay, :update?
+      @relay.disable!
+      redirect_to admin_relays_path
+    end
+
+    private
+
+    def set_relay
+      @relay = Relay.find(params[:id])
+    end
+
+    def resource_params
+      params.require(:relay).permit(:inbox_url)
+    end
+  end
+end
diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb
index d00b3d2227357dec958d7d1e164d52de1b57f624..f138376b2f73611cea0ff4b6c102784a14714156 100644
--- a/app/controllers/admin/reports_controller.rb
+++ b/app/controllers/admin/reports_controller.rb
@@ -13,72 +13,42 @@ module Admin
       authorize @report, :show?
 
       @report_note  = @report.notes.new
-      @report_notes = (@report.notes.latest + @report.history).sort_by(&:created_at)
+      @report_notes = (@report.notes.latest + @report.history + @report.target_account.targeted_account_warnings.latest.custom).sort_by(&:created_at)
       @form         = Form::StatusBatch.new
     end
 
-    def update
+    def assign_to_self
       authorize @report, :update?
-      process_report
-
-      if @report.action_taken?
-        redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
-      else
-        redirect_to admin_report_path(@report)
-      end
+      @report.update!(assigned_account_id: current_account.id)
+      log_action :assigned_to_self, @report
+      redirect_to admin_report_path(@report)
     end
 
-    private
-
-    def process_report
-      case params[:outcome].to_s
-      when 'assign_to_self'
-        @report.update!(assigned_account_id: current_account.id)
-        log_action :assigned_to_self, @report
-      when 'unassign'
-        @report.update!(assigned_account_id: nil)
-        log_action :unassigned, @report
-      when 'reopen'
-        @report.unresolve!
-        log_action :reopen, @report
-      when 'resolve'
-        @report.resolve!(current_account)
-        log_action :resolve, @report
-      when 'suspend'
-        Admin::SuspensionWorker.perform_async(@report.target_account.id)
-
-        log_action :resolve, @report
-        log_action :suspend, @report.target_account
-
-        resolve_all_target_account_reports
-      when 'silence'
-        @report.target_account.update!(silenced: true)
-
-        log_action :resolve, @report
-        log_action :silence, @report.target_account
-
-        resolve_all_target_account_reports
-      else
-        raise ActiveRecord::RecordNotFound
-      end
-      @report.reload
+    def unassign
+      authorize @report, :update?
+      @report.update!(assigned_account_id: nil)
+      log_action :unassigned, @report
+      redirect_to admin_report_path(@report)
     end
 
-    def resolve_all_target_account_reports
-      unresolved_reports_for_target_account.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
+    def reopen
+      authorize @report, :update?
+      @report.unresolve!
+      log_action :reopen, @report
+      redirect_to admin_report_path(@report)
     end
 
-    def unresolved_reports_for_target_account
-      Report.where(
-        target_account: @report.target_account
-      ).unresolved
+    def resolve
+      authorize @report, :update?
+      @report.resolve!(current_account)
+      log_action :resolve, @report
+      redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
     end
 
+    private
+
     def filtered_reports
-      ReportFilter.new(filter_params).results.order(id: :desc).includes(
-        :account,
-        :target_account
-      )
+      ReportFilter.new(filter_params).results.order(id: :desc).includes(:account, :target_account)
     end
 
     def filter_params
diff --git a/app/controllers/admin/resets_controller.rb b/app/controllers/admin/resets_controller.rb
index 3e27d01ac2719efc5c409737de3543833071f284..db8f61d64cb13f4590639f36f5e8169d8e74a378 100644
--- a/app/controllers/admin/resets_controller.rb
+++ b/app/controllers/admin/resets_controller.rb
@@ -10,11 +10,5 @@ module Admin
       log_action :reset_password, @user
       redirect_to admin_accounts_path
     end
-
-    private
-
-    def set_user
-      @user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
-    end
   end
 end
diff --git a/app/controllers/admin/roles_controller.rb b/app/controllers/admin/roles_controller.rb
index af7ec0740d2a89b90ba03ab38cd9c18b7260a503..13f56e9beb52b983accd4c53cd6a05a037b63f6f 100644
--- a/app/controllers/admin/roles_controller.rb
+++ b/app/controllers/admin/roles_controller.rb
@@ -17,11 +17,5 @@ module Admin
       log_action :demote, @user
       redirect_to admin_account_path(@user.account_id)
     end
-
-    private
-
-    def set_user
-      @user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
-    end
   end
 end
diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb
index 75d00326c76f86f00412bbe05251f45c5cb773a8..4a049fc235638a649dad3f4045e6c2a521f36b84 100644
--- a/app/controllers/admin/settings_controller.rb
+++ b/app/controllers/admin/settings_controller.rb
@@ -6,6 +6,7 @@ module Admin
       site_contact_username
       site_contact_email
       site_title
+      site_short_description
       site_description
       site_extended_description
       site_terms
@@ -15,13 +16,17 @@ module Admin
       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(
@@ -33,11 +38,13 @@ module Admin
       peers_api_enabled
       show_known_fediverse_at_about_page
       preview_sensitive_media
+      profile_directory
     ).freeze
 
     UPLOAD_SETTINGS = %w(
       thumbnail
       hero
+      mascot
     ).freeze
 
     def edit
diff --git a/app/controllers/admin/silences_controller.rb b/app/controllers/admin/silences_controller.rb
deleted file mode 100644
index 4c06a9c0cc7b051f8478be29917e3a2073d89693..0000000000000000000000000000000000000000
--- a/app/controllers/admin/silences_controller.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Admin
-  class SilencesController < BaseController
-    before_action :set_account
-
-    def create
-      authorize @account, :silence?
-      @account.update!(silenced: true)
-      log_action :silence, @account
-      redirect_to admin_accounts_path
-    end
-
-    def destroy
-      authorize @account, :unsilence?
-      @account.update!(silenced: false)
-      log_action :unsilence, @account
-      redirect_to admin_accounts_path
-    end
-
-    private
-
-    def set_account
-      @account = Account.find(params[:account_id])
-    end
-  end
-end
diff --git a/app/controllers/admin/statuses_controller.rb b/app/controllers/admin/statuses_controller.rb
index 382bfc4a23fa67a751e534b78bca32639475af80..650195034691663baea2e47244abbf5c56da89d0 100644
--- a/app/controllers/admin/statuses_controller.rb
+++ b/app/controllers/admin/statuses_controller.rb
@@ -22,12 +22,25 @@ module Admin
       @form     = Form::StatusBatch.new
     end
 
+    def show
+      authorize :status, :index?
+
+      @statuses = @account.statuses.where(id: params[:id])
+      authorize @statuses.first, :show?
+
+      @form = Form::StatusBatch.new
+    end
+
     def create
       authorize :status, :update?
 
       @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_account_statuses_path(@account.id, current_params)
+    rescue ActionController::ParameterMissing
+      flash[:alert] = I18n.t('admin.statuses.no_status_selected')
+
       redirect_to admin_account_statuses_path(@account.id, current_params)
     end
 
diff --git a/app/controllers/admin/suspensions_controller.rb b/app/controllers/admin/suspensions_controller.rb
deleted file mode 100644
index 5f222e12588ee970904f3dd01a421c1ddb6df118..0000000000000000000000000000000000000000
--- a/app/controllers/admin/suspensions_controller.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Admin
-  class SuspensionsController < BaseController
-    before_action :set_account
-
-    def create
-      authorize @account, :suspend?
-      Admin::SuspensionWorker.perform_async(@account.id)
-      log_action :suspend, @account
-      redirect_to admin_accounts_path
-    end
-
-    def destroy
-      authorize @account, :unsuspend?
-      @account.unsuspend!
-      log_action :unsuspend, @account
-      redirect_to admin_accounts_path
-    end
-
-    private
-
-    def set_account
-      @account = Account.find(params[:account_id])
-    end
-  end
-end
diff --git a/app/controllers/admin/tags_controller.rb b/app/controllers/admin/tags_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e9f4f2cfa3b35a67101d0957ee6a22f1f66f41fc
--- /dev/null
+++ b/app/controllers/admin/tags_controller.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Admin
+  class TagsController < BaseController
+    before_action :set_tags, only: :index
+    before_action :set_tag, except: :index
+    before_action :set_filter_params
+
+    def index
+      authorize :tag, :index?
+    end
+
+    def hide
+      authorize @tag, :hide?
+      @tag.account_tag_stat.update!(hidden: true)
+      redirect_to admin_tags_path(@filter_params)
+    end
+
+    def unhide
+      authorize @tag, :unhide?
+      @tag.account_tag_stat.update!(hidden: false)
+      redirect_to admin_tags_path(@filter_params)
+    end
+
+    private
+
+    def set_tags
+      @tags = Tag.discoverable
+      @tags.merge!(Tag.hidden) if filter_params[:hidden]
+    end
+
+    def set_tag
+      @tag = Tag.find(params[:id])
+    end
+
+    def set_filter_params
+      @filter_params = filter_params.to_hash.symbolize_keys
+    end
+
+    def filter_params
+      params.permit(:hidden)
+    end
+  end
+end
diff --git a/app/controllers/admin/two_factor_authentications_controller.rb b/app/controllers/admin/two_factor_authentications_controller.rb
index 0221072032566453ae2274d96a0f966c4eb4b813..2577a4b17fff4b59c93a506e4f0fecca0cbcb4cc 100644
--- a/app/controllers/admin/two_factor_authentications_controller.rb
+++ b/app/controllers/admin/two_factor_authentications_controller.rb
@@ -2,7 +2,7 @@
 
 module Admin
   class TwoFactorAuthenticationsController < BaseController
-    before_action :set_user
+    before_action :set_target_user
 
     def destroy
       authorize @user, :disable_2fa?
@@ -13,7 +13,7 @@ module Admin
 
     private
 
-    def set_user
+    def set_target_user
       @user = User.find(params[:user_id])
     end
   end
diff --git a/app/controllers/admin/warning_presets_controller.rb b/app/controllers/admin/warning_presets_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..37be842c5b055fabbdbe91d1b5222c0770e66ca5
--- /dev/null
+++ b/app/controllers/admin/warning_presets_controller.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Admin
+  class WarningPresetsController < BaseController
+    before_action :set_warning_preset, except: [:index, :create]
+
+    def index
+      authorize :account_warning_preset, :index?
+
+      @warning_presets = AccountWarningPreset.all
+      @warning_preset  = AccountWarningPreset.new
+    end
+
+    def create
+      authorize :account_warning_preset, :create?
+
+      @warning_preset = AccountWarningPreset.new(warning_preset_params)
+
+      if @warning_preset.save
+        redirect_to admin_warning_presets_path
+      else
+        @warning_presets = AccountWarningPreset.all
+        render :index
+      end
+    end
+
+    def edit
+      authorize @warning_preset, :update?
+    end
+
+    def update
+      authorize @warning_preset, :update?
+
+      if @warning_preset.update(warning_preset_params)
+        redirect_to admin_warning_presets_path
+      else
+        render :edit
+      end
+    end
+
+    def destroy
+      authorize @warning_preset, :destroy?
+
+      @warning_preset.destroy!
+      redirect_to admin_warning_presets_path
+    end
+
+    private
+
+    def set_warning_preset
+      @warning_preset = AccountWarningPreset.find(params[:id])
+    end
+
+    def warning_preset_params
+      params.require(:account_warning_preset).permit(:text)
+    end
+  end
+end
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index 770a69921a8a4da6f1bc78de85a8afc0ec005b3f..a1dd30918f34550758f1b5c3d7d38c1bfd0a1b8d 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -7,6 +7,8 @@ class Api::BaseController < ApplicationController
   include RateLimitHeaders
 
   skip_before_action :store_current_location
+  skip_before_action :check_user_permissions
+
   protect_from_forgery with: :null_session
 
   rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
@@ -51,8 +53,8 @@ class Api::BaseController < ApplicationController
     [params[:limit].to_i.abs, default_limit * 2].min
   end
 
-  def truthy_param?(key)
-    ActiveModel::Type::Boolean.new.cast(params[key])
+  def params_slice(*keys)
+    params.slice(*keys).permit(*keys)
   end
 
   def current_resource_owner
@@ -66,12 +68,14 @@ class Api::BaseController < ApplicationController
   end
 
   def require_user!
-    if current_user && !current_user.disabled?
-      set_user_activity
-    elsif current_user
+    if !current_user
+      render json: { error: 'This method requires an authenticated user' }, status: 422
+    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
     else
-      render json: { error: 'This method requires an authenticated user' }, status: 422
+      set_user_activity
     end
   end
 
diff --git a/app/controllers/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb
index dcd41b35c1b3722a30483650e69bcb783219cad3..e77f57910b2bfbcbe11c0fb958bb7b9eb43e3f63 100644
--- a/app/controllers/api/v1/accounts/credentials_controller.rb
+++ b/app/controllers/api/v1/accounts/credentials_controller.rb
@@ -21,7 +21,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
   private
 
   def account_params
-    params.permit(:display_name, :note, :avatar, :header, :locked, :bot, fields_attributes: [:name, :value])
+    params.permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, fields_attributes: [:name, :value])
   end
 
   def user_settings_params
diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
index daa35769ebf12a6c078d5694924cecdd9b06f6cd..ec15debb0cf4646f640477765acfc126af3a2e29 100644
--- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
@@ -25,7 +25,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
   end
 
   def default_accounts
-    Account.includes(:active_relationships).references(:active_relationships)
+    Account.includes(:active_relationships, :account_stat).references(:active_relationships)
   end
 
   def paginated_follows
diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb
index 6be97b87ece4c131275b2ed611b5367728ee5988..f3e112f2c3e2e80714d43697015f5dbf09bf9958 100644
--- a/app/controllers/api/v1/accounts/following_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb
@@ -25,7 +25,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
   end
 
   def default_accounts
-    Account.includes(:passive_relationships).references(:passive_relationships)
+    Account.includes(:passive_relationships, :account_stat).references(:passive_relationships)
   end
 
   def paginated_follows
diff --git a/app/controllers/api/v1/accounts/pins_controller.rb b/app/controllers/api/v1/accounts/pins_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0a0239c424e8bf3e9325173be13947034518b03e
--- /dev/null
+++ b/app/controllers/api/v1/accounts/pins_controller.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class Api::V1::Accounts::PinsController < Api::BaseController
+  include Authorization
+
+  before_action -> { doorkeeper_authorize! :write, :'write:accounts' }
+  before_action :require_user!
+  before_action :set_account
+
+  respond_to :json
+
+  def create
+    AccountPin.create!(account: current_account, target_account: @account)
+    render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
+  end
+
+  def destroy
+    pin = AccountPin.find_by(account: current_account, target_account: @account)
+    pin&.destroy!
+    render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
+  end
+
+  private
+
+  def set_account
+    @account = Account.find(params[:account_id])
+  end
+
+  def relationships_presenter
+    AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
+  end
+end
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index 06fa6c762399f70603e8e6203011489558b517e4..6c2a5c141431c17d579cf6f2d4c017086b702bd2 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Accounts::StatusesController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
+  before_action -> { authorize_if_got_token! :read, :'read:statuses' }
   before_action :set_account
   after_action :insert_pagination_headers
 
@@ -28,14 +28,11 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
 
   def account_statuses
     statuses = truthy_param?(:pinned) ? pinned_scope : permitted_account_statuses
-    statuses = statuses.paginate_by_max_id(
-      limit_param(DEFAULT_STATUSES_LIMIT),
-      params[:max_id],
-      params[:since_id]
-    )
+    statuses = statuses.paginate_by_id(limit_param(DEFAULT_STATUSES_LIMIT), params_slice(:max_id, :since_id, :min_id))
 
     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
   end
@@ -66,6 +63,10 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
     Status.without_replies
   end
 
+  def no_reblogs_scope
+    Status.without_reblogs
+  end
+
   def pagination_params(core_params)
     params.slice(:limit, :only_media, :exclude_replies).permit(:limit, :only_media, :exclude_replies).merge(core_params)
   end
@@ -82,7 +83,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
 
   def prev_path
     unless @statuses.empty?
-      api_v1_account_statuses_url pagination_params(since_id: pagination_since_id)
+      api_v1_account_statuses_url pagination_params(min_id: pagination_since_id)
     end
   end
 
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 1d5372a8cdd4f2d7d0793119d99545efd1deba00..2ccbc3cbbdf50e1d64cd6292a3bdb133b29759c5 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -1,14 +1,16 @@
 # frozen_string_literal: true
 
 class Api::V1::AccountsController < Api::BaseController
-  before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
+  before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:create, :follow, :unfollow, :block, :unblock, :mute, :unmute]
   before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, only: [:follow, :unfollow]
   before_action -> { doorkeeper_authorize! :follow, :'write:mutes' }, only: [:mute, :unmute]
   before_action -> { doorkeeper_authorize! :follow, :'write:blocks' }, only: [:block, :unblock]
+  before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:create]
 
-  before_action :require_user!, except: [:show]
-  before_action :set_account
+  before_action :require_user!, except: [:show, :create]
+  before_action :set_account, except: [:create]
   before_action :check_account_suspension, only: [:show]
+  before_action :check_enabled_registrations, only: [:create]
 
   respond_to :json
 
@@ -16,8 +18,18 @@ class Api::V1::AccountsController < Api::BaseController
     render json: @account, serializer: REST::AccountSerializer
   end
 
+  def create
+    token    = AppSignUpService.new.call(doorkeeper_token.application, account_params)
+    response = Doorkeeper::OAuth::TokenResponse.new(token)
+
+    headers.merge!(response.headers)
+
+    self.response_body = Oj.dump(response.body)
+    self.status        = response.status
+  end
+
   def follow
-    FollowService.new.call(current_user.account, @account.acct, reblogs: truthy_param?(:reblogs))
+    FollowService.new.call(current_user.account, @account, reblogs: truthy_param?(:reblogs))
 
     options = @account.locked? ? {} : { following_map: { @account.id => { reblogs: truthy_param?(:reblogs) } }, requested_map: { @account.id => false } }
 
@@ -62,4 +74,12 @@ class Api::V1::AccountsController < Api::BaseController
   def check_account_suspension
     gone if @account.suspended?
   end
+
+  def account_params
+    params.permit(:username, :email, :password, :agreement, :locale)
+  end
+
+  def check_enabled_registrations
+    forbidden if single_user_mode? || !Setting.open_registrations
+  end
 end
diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb
index 99c53d59af8bf9b70b067049bce8e89e6856dfeb..4cff04cad7fd1506a19094e936a89f019d14b73a 100644
--- a/app/controllers/api/v1/blocks_controller.rb
+++ b/app/controllers/api/v1/blocks_controller.rb
@@ -19,7 +19,7 @@ class Api::V1::BlocksController < Api::BaseController
   end
 
   def paginated_blocks
-    @paginated_blocks ||= Block.eager_load(:target_account)
+    @paginated_blocks ||= Block.eager_load(target_account: :account_stat)
                                .where(account: current_account)
                                .paginate_by_max_id(
                                  limit_param(DEFAULT_ACCOUNTS_LIMIT),
diff --git a/app/controllers/api/v1/conversations_controller.rb b/app/controllers/api/v1/conversations_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b19f27ebfb6c4750a64dbd83cfa014ffae464d4e
--- /dev/null
+++ b/app/controllers/api/v1/conversations_controller.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+class Api::V1::ConversationsController < Api::BaseController
+  LIMIT = 20
+
+  before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :index
+  before_action -> { doorkeeper_authorize! :write, :'write:conversations' }, except: :index
+  before_action :require_user!
+  before_action :set_conversation, except: :index
+  after_action :insert_pagination_headers, only: :index
+
+  respond_to :json
+
+  def index
+    @conversations = paginated_conversations
+    render json: @conversations, each_serializer: REST::ConversationSerializer
+  end
+
+  def read
+    @conversation.update!(unread: false)
+    render json: @conversation, serializer: REST::ConversationSerializer
+  end
+
+  def destroy
+    @conversation.destroy!
+    render_empty
+  end
+
+  private
+
+  def set_conversation
+    @conversation = AccountConversation.where(account: current_account).find(params[:id])
+  end
+
+  def paginated_conversations
+    AccountConversation.where(account: current_account)
+                       .paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
+  end
+
+  def insert_pagination_headers
+    set_pagination_headers(next_path, prev_path)
+  end
+
+  def next_path
+    if records_continue?
+      api_v1_conversations_url pagination_params(max_id: pagination_max_id)
+    end
+  end
+
+  def prev_path
+    unless @conversations.empty?
+      api_v1_conversations_url pagination_params(min_id: pagination_since_id)
+    end
+  end
+
+  def pagination_max_id
+    @conversations.last.last_status_id
+  end
+
+  def pagination_since_id
+    @conversations.first.last_status_id
+  end
+
+  def records_continue?
+    @conversations.size == limit_param(LIMIT)
+  end
+
+  def pagination_params(core_params)
+    params.slice(:limit).permit(:limit).merge(core_params)
+  end
+end
diff --git a/app/controllers/api/v1/custom_emojis_controller.rb b/app/controllers/api/v1/custom_emojis_controller.rb
index f8cd64455a009bb3aacbe8e5763f278cc393f451..7bac27da4b78dd3689f16794751c525f1870e029 100644
--- a/app/controllers/api/v1/custom_emojis_controller.rb
+++ b/app/controllers/api/v1/custom_emojis_controller.rb
@@ -4,6 +4,8 @@ class Api::V1::CustomEmojisController < Api::BaseController
   respond_to :json
 
   def index
-    render json: CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer
+    render_cached_json('api:v1:custom_emojis', expires_in: 1.minute) do
+      ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer)
+    end
   end
 end
diff --git a/app/controllers/api/v1/endorsements_controller.rb b/app/controllers/api/v1/endorsements_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2770c7aef67825859f24af7af8b2a21536b1e6c3
--- /dev/null
+++ b/app/controllers/api/v1/endorsements_controller.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+class Api::V1::EndorsementsController < Api::BaseController
+  before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
+  before_action :require_user!
+  after_action :insert_pagination_headers
+
+  respond_to :json
+
+  def index
+    @accounts = load_accounts
+    render json: @accounts, each_serializer: REST::AccountSerializer
+  end
+
+  private
+
+  def load_accounts
+    if unlimited?
+      endorsed_accounts.all
+    else
+      endorsed_accounts.paginate_by_max_id(
+        limit_param(DEFAULT_ACCOUNTS_LIMIT),
+        params[:max_id],
+        params[:since_id]
+      )
+    end
+  end
+
+  def endorsed_accounts
+    current_account.endorsed_accounts.includes(:account_stat)
+  end
+
+  def insert_pagination_headers
+    set_pagination_headers(next_path, prev_path)
+  end
+
+  def next_path
+    return if unlimited?
+
+    if records_continue?
+      api_v1_endorsements_url pagination_params(max_id: pagination_max_id)
+    end
+  end
+
+  def prev_path
+    return if unlimited?
+
+    unless @accounts.empty?
+      api_v1_endorsements_url pagination_params(since_id: pagination_since_id)
+    end
+  end
+
+  def pagination_max_id
+    @accounts.last.id
+  end
+
+  def pagination_since_id
+    @accounts.first.id
+  end
+
+  def records_continue?
+    @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
+  end
+
+  def pagination_params(core_params)
+    params.slice(:limit).permit(:limit).merge(core_params)
+  end
+
+  def unlimited?
+    params[:limit] == '0'
+  end
+end
diff --git a/app/controllers/api/v1/favourites_controller.rb b/app/controllers/api/v1/favourites_controller.rb
index ab5204355cd620a4b6f5765c6ed4d51e07b7eb35..db827f9d4aa2aae2452c42fe2f475520e73e266f 100644
--- a/app/controllers/api/v1/favourites_controller.rb
+++ b/app/controllers/api/v1/favourites_controller.rb
@@ -26,10 +26,9 @@ class Api::V1::FavouritesController < Api::BaseController
   end
 
   def results
-    @_results ||= account_favourites.paginate_by_max_id(
+    @_results ||= account_favourites.paginate_by_id(
       limit_param(DEFAULT_STATUSES_LIMIT),
-      params[:max_id],
-      params[:since_id]
+      params_slice(:max_id, :since_id, :min_id)
     )
   end
 
@@ -49,7 +48,7 @@ class Api::V1::FavouritesController < Api::BaseController
 
   def prev_path
     unless results.empty?
-      api_v1_favourites_url pagination_params(since_id: pagination_since_id)
+      api_v1_favourites_url pagination_params(min_id: pagination_since_id)
     end
   end
 
diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb
index 313fe2f81ce82eda317a31b8dc3ce88070b3f178..e6888154e22217c23f79fd70d64ebd3c37cbd219 100644
--- a/app/controllers/api/v1/follow_requests_controller.rb
+++ b/app/controllers/api/v1/follow_requests_controller.rb
@@ -13,6 +13,7 @@ class Api::V1::FollowRequestsController < Api::BaseController
 
   def authorize
     AuthorizeFollowService.new.call(account, current_account)
+    NotifyService.new.call(current_account, Follow.find_by(account: account, target_account: current_account))
     render_empty
   end
 
@@ -32,7 +33,7 @@ class Api::V1::FollowRequestsController < Api::BaseController
   end
 
   def default_accounts
-    Account.includes(:follow_requests).references(:follow_requests)
+    Account.includes(:follow_requests, :account_stat).references(:follow_requests)
   end
 
   def paginated_follow_requests
diff --git a/app/controllers/api/v1/instances_controller.rb b/app/controllers/api/v1/instances_controller.rb
index 1c6971c1828a87dd25eca3408664591482b6cba6..5686e8d7c394e5a5c510fd0e28a465f133c68204 100644
--- a/app/controllers/api/v1/instances_controller.rb
+++ b/app/controllers/api/v1/instances_controller.rb
@@ -4,6 +4,8 @@ class Api::V1::InstancesController < Api::BaseController
   respond_to :json
 
   def show
-    render json: {}, serializer: REST::InstanceSerializer
+    render_cached_json('api:v1:instances', expires_in: 5.minutes) do
+      ActiveModelSerializers::SerializableResource.new({}, serializer: REST::InstanceSerializer)
+    end
   end
 end
diff --git a/app/controllers/api/v1/lists/accounts_controller.rb b/app/controllers/api/v1/lists/accounts_controller.rb
index 19de567321641d1503ef790e05be47cc743f06e9..23078263e7abdd70843a62906245afd35774fb3b 100644
--- a/app/controllers/api/v1/lists/accounts_controller.rb
+++ b/app/controllers/api/v1/lists/accounts_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Lists::AccountsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read, :'read:lists' },    only:  [:show]
+  before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:show]
   before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:show]
 
   before_action :require_user!
@@ -37,9 +37,9 @@ class Api::V1::Lists::AccountsController < Api::BaseController
 
   def load_accounts
     if unlimited?
-      @list.accounts.all
+      @list.accounts.includes(:account_stat).all
     else
-      @list.accounts.paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
+      @list.accounts.includes(:account_stat).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
     end
   end
 
diff --git a/app/controllers/api/v1/lists_controller.rb b/app/controllers/api/v1/lists_controller.rb
index b42b8b9710d2a9f42f5d32d4ede3c8875624203e..054172bee3aa64e25a19751bda99d814854bdc61 100644
--- a/app/controllers/api/v1/lists_controller.rb
+++ b/app/controllers/api/v1/lists_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::ListsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read, :'read:lists' },    only:  [:index, :show]
+  before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:index, :show]
   before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:index, :show]
 
   before_action :require_user!
diff --git a/app/controllers/api/v1/mutes_controller.rb b/app/controllers/api/v1/mutes_controller.rb
index faa7d16cd9f59ef2ae3263bde6770063eebc5e00..df6c8e86c5960953312ce3445703ce6716087156 100644
--- a/app/controllers/api/v1/mutes_controller.rb
+++ b/app/controllers/api/v1/mutes_controller.rb
@@ -15,19 +15,17 @@ class Api::V1::MutesController < Api::BaseController
   private
 
   def load_accounts
-    default_accounts.merge(paginated_mutes).to_a
-  end
-
-  def default_accounts
-    Account.includes(:muted_by).references(:muted_by)
+    paginated_mutes.map(&:target_account)
   end
 
   def paginated_mutes
-    Mute.where(account: current_account).paginate_by_max_id(
-      limit_param(DEFAULT_ACCOUNTS_LIMIT),
-      params[:max_id],
-      params[:since_id]
-    )
+    @paginated_mutes ||= Mute.eager_load(:target_account)
+                             .where(account: current_account)
+                             .paginate_by_max_id(
+                               limit_param(DEFAULT_ACCOUNTS_LIMIT),
+                               params[:max_id],
+                               params[:since_id]
+                             )
   end
 
   def insert_pagination_headers
@@ -41,21 +39,21 @@ class Api::V1::MutesController < Api::BaseController
   end
 
   def prev_path
-    unless @accounts.empty?
+    unless paginated_mutes.empty?
       api_v1_mutes_url pagination_params(since_id: pagination_since_id)
     end
   end
 
   def pagination_max_id
-    @accounts.last.muted_by_ids.last
+    paginated_mutes.last.id
   end
 
   def pagination_since_id
-    @accounts.first.muted_by_ids.first
+    paginated_mutes.first.id
   end
 
   def records_continue?
-    @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
+    paginated_mutes.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
   end
 
   def pagination_params(core_params)
diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb
index 593c8f9a9c8a201e4218479bd642a5f0a3a67fca..e2dec62afaef4a4d07cf982649369f6042515239 100644
--- a/app/controllers/api/v1/notifications_controller.rb
+++ b/app/controllers/api/v1/notifications_controller.rb
@@ -37,10 +37,9 @@ class Api::V1::NotificationsController < Api::BaseController
   end
 
   def paginated_notifications
-    browserable_account_notifications.paginate_by_max_id(
+    browserable_account_notifications.paginate_by_id(
       limit_param(DEFAULT_NOTIFICATIONS_LIMIT),
-      params[:max_id],
-      params[:since_id]
+      params_slice(:max_id, :since_id, :min_id)
     )
   end
 
@@ -64,7 +63,7 @@ class Api::V1::NotificationsController < Api::BaseController
 
   def prev_path
     unless @notifications.empty?
-      api_v1_notifications_url pagination_params(since_id: pagination_since_id)
+      api_v1_notifications_url pagination_params(min_id: pagination_since_id)
     end
   end
 
diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb
index a954101cb8fee46da9ed91f1cd807dc96e5d22ac..e182a9c6cf6245fb052b435416e2d667ba212390 100644
--- a/app/controllers/api/v1/reports_controller.rb
+++ b/app/controllers/api/v1/reports_controller.rb
@@ -1,17 +1,11 @@
 # frozen_string_literal: true
 
 class Api::V1::ReportsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read, :'read:reports' }, except: [:create]
   before_action -> { doorkeeper_authorize! :write, :'write:reports' }, only: [:create]
   before_action :require_user!
 
   respond_to :json
 
-  def index
-    @reports = current_account.reports
-    render json: @reports, each_serializer: REST::ReportSerializer
-  end
-
   def create
     @report = ReportService.new.call(
       current_account,
@@ -27,7 +21,7 @@ class Api::V1::ReportsController < Api::BaseController
   private
 
   def reported_status_ids
-    Status.find(status_ids).pluck(:id)
+    reported_account.statuses.find(status_ids).pluck(:id)
   end
 
   def status_ids
diff --git a/app/controllers/api/v1/scheduled_statuses_controller.rb b/app/controllers/api/v1/scheduled_statuses_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9950296f3bc8f72b2ccd9930144daf4e6d630aa9
--- /dev/null
+++ b/app/controllers/api/v1/scheduled_statuses_controller.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+class Api::V1::ScheduledStatusesController < Api::BaseController
+  include Authorization
+
+  before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, except: [:update, :destroy]
+  before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:update, :destroy]
+
+  before_action :set_statuses, only: :index
+  before_action :set_status, except: :index
+
+  after_action :insert_pagination_headers, only: :index
+
+  def index
+    render json: @statuses, each_serializer: REST::ScheduledStatusSerializer
+  end
+
+  def show
+    render json: @status, serializer: REST::ScheduledStatusSerializer
+  end
+
+  def update
+    @status.update!(scheduled_status_params)
+    render json: @status, serializer: REST::ScheduledStatusSerializer
+  end
+
+  def destroy
+    @status.destroy!
+    render_empty
+  end
+
+  private
+
+  def set_statuses
+    @statuses = current_account.scheduled_statuses.paginate_by_id(limit_param(DEFAULT_STATUSES_LIMIT), params_slice(:max_id, :since_id, :min_id))
+  end
+
+  def set_status
+    @status = current_account.scheduled_statuses.find(params[:id])
+  end
+
+  def scheduled_status_params
+    params.permit(:scheduled_at)
+  end
+
+  def pagination_params(core_params)
+    params.slice(:limit).permit(:limit).merge(core_params)
+  end
+
+  def insert_pagination_headers
+    set_pagination_headers(next_path, prev_path)
+  end
+
+  def next_path
+    if records_continue?
+      api_v1_scheduled_statuses_url pagination_params(max_id: pagination_max_id)
+    end
+  end
+
+  def prev_path
+    unless @statuses.empty?
+      api_v1_scheduled_statuses_url pagination_params(min_id: pagination_since_id)
+    end
+  end
+
+  def records_continue?
+    @statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
+  end
+
+  def pagination_max_id
+    @statuses.last.id
+  end
+
+  def pagination_since_id
+    @statuses.first.id
+  end
+end
diff --git a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
index 8f4070bc781adedd70f6b90f079d455eefcafbab..657e57831989dbbf56890f540632c4d25ff72bd9 100644
--- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
@@ -22,7 +22,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
 
   def default_accounts
     Account
-      .includes(:favourites)
+      .includes(:favourites, :account_stat)
       .references(:favourites)
       .where(favourites: { status_id: @status.id })
   end
diff --git a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
index 93b83ce485179690dc23c83d78af0e419d43a138..6851099f6612cd794c456291e2b788e71cb3cb4b 100644
--- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
@@ -21,11 +21,11 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
   end
 
   def default_accounts
-    Account.includes(:statuses).references(:statuses)
+    Account.includes(:statuses, :account_stat).references(:statuses)
   end
 
   def paginated_statuses
-    Status.where(reblog_of_id: @status.id).paginate_by_max_id(
+    Status.where(reblog_of_id: @status.id).where(visibility: [:public, :unlisted]).paginate_by_max_id(
       limit_param(DEFAULT_ACCOUNTS_LIMIT),
       params[:max_id],
       params[:since_id]
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index c6925d46292de0a837fb6fae8793bfc23e4d344f..29b420c67525f7560d6f01bdee9e1d24ce26c668 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -17,8 +17,7 @@ class Api::V1::StatusesController < Api::BaseController
   CONTEXT_LIMIT = 4_096
 
   def show
-    cached  = Rails.cache.read(@status.cache_key)
-    @status = cached unless cached.nil?
+    @status = cache_collection([@status], Status).first
     render json: @status, serializer: REST::StatusSerializer
   end
 
@@ -46,16 +45,17 @@ class Api::V1::StatusesController < Api::BaseController
 
   def create
     @status = PostStatusService.new.call(current_user.account,
-                                         status_params[:status],
-                                         status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]),
+                                         text: status_params[:status],
+                                         thread: status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]),
                                          media_ids: status_params[:media_ids],
                                          sensitive: status_params[:sensitive],
                                          spoiler_text: status_params[:spoiler_text],
                                          visibility: status_params[:visibility],
+                                         scheduled_at: status_params[:scheduled_at],
                                          application: doorkeeper_token.application,
                                          idempotency: request.headers['Idempotency-Key'])
 
-    render json: @status, serializer: REST::StatusSerializer
+    render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer
   end
 
   def destroy
@@ -78,7 +78,7 @@ class Api::V1::StatusesController < Api::BaseController
   end
 
   def status_params
-    params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, media_ids: [])
+    params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, :scheduled_at, media_ids: [])
   end
 
   def pagination_params(core_params)
diff --git a/app/controllers/api/v1/timelines/home_controller.rb b/app/controllers/api/v1/timelines/home_controller.rb
index 4412aaaa391c7f0dca66d03e7741e476c5aee86e..fcd0757f1a87c0d6792cfb12de536d9ef46c4643 100644
--- a/app/controllers/api/v1/timelines/home_controller.rb
+++ b/app/controllers/api/v1/timelines/home_controller.rb
@@ -30,7 +30,8 @@ class Api::V1::Timelines::HomeController < Api::BaseController
     account_home_feed.get(
       limit_param(DEFAULT_STATUSES_LIMIT),
       params[:max_id],
-      params[:since_id]
+      params[:since_id],
+      params[:min_id]
     )
   end
 
@@ -51,7 +52,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
   end
 
   def prev_path
-    api_v1_timelines_home_url pagination_params(since_id: pagination_since_id)
+    api_v1_timelines_home_url pagination_params(min_id: pagination_since_id)
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/timelines/list_controller.rb b/app/controllers/api/v1/timelines/list_controller.rb
index cfc5f3b5e4d68326ffe03161f96ec5dd65863c93..a15eae468d92b44f0c3228192d144d9e045ba034 100644
--- a/app/controllers/api/v1/timelines/list_controller.rb
+++ b/app/controllers/api/v1/timelines/list_controller.rb
@@ -32,7 +32,8 @@ class Api::V1::Timelines::ListController < Api::BaseController
     list_feed.get(
       limit_param(DEFAULT_STATUSES_LIMIT),
       params[:max_id],
-      params[:since_id]
+      params[:since_id],
+      params[:min_id]
     )
   end
 
@@ -53,7 +54,7 @@ class Api::V1::Timelines::ListController < Api::BaseController
   end
 
   def prev_path
-    api_v1_timelines_list_url params[:id], pagination_params(since_id: pagination_since_id)
+    api_v1_timelines_list_url params[:id], pagination_params(min_id: pagination_since_id)
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb
index 13fe015b7df335b550b1678e313517d11238a2cf..aabe24324312421b5f9c0765b3a7c037907ab9df 100644
--- a/app/controllers/api/v1/timelines/public_controller.rb
+++ b/app/controllers/api/v1/timelines/public_controller.rb
@@ -21,10 +21,9 @@ class Api::V1::Timelines::PublicController < Api::BaseController
   end
 
   def public_statuses
-    statuses = public_timeline_statuses.paginate_by_max_id(
+    statuses = public_timeline_statuses.paginate_by_id(
       limit_param(DEFAULT_STATUSES_LIMIT),
-      params[:max_id],
-      params[:since_id]
+      params_slice(:max_id, :since_id, :min_id)
     )
 
     if truthy_param?(:only_media)
@@ -53,7 +52,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
   end
 
   def prev_path
-    api_v1_timelines_public_url pagination_params(since_id: pagination_since_id)
+    api_v1_timelines_public_url pagination_params(min_id: pagination_since_id)
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb
index 7de49a5ed683598a6fc2392fb2edbd88399dad63..92c32c1784b2e2c56a689c0284294f0c26a298a0 100644
--- a/app/controllers/api/v1/timelines/tag_controller.rb
+++ b/app/controllers/api/v1/timelines/tag_controller.rb
@@ -29,10 +29,9 @@ class Api::V1::Timelines::TagController < Api::BaseController
     if @tag.nil?
       []
     else
-      statuses = tag_timeline_statuses.paginate_by_max_id(
+      statuses = tag_timeline_statuses.paginate_by_id(
         limit_param(DEFAULT_STATUSES_LIMIT),
-        params[:max_id],
-        params[:since_id]
+        params_slice(:max_id, :since_id, :min_id)
       )
 
       if truthy_param?(:only_media)
@@ -46,7 +45,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
   end
 
   def tag_timeline_statuses
-    Status.as_tag_timeline(@tag, current_account, truthy_param?(:local))
+    HashtagQueryService.new.call(@tag, params.slice(:any, :all, :none), current_account, truthy_param?(:local))
   end
 
   def insert_pagination_headers
@@ -62,7 +61,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
   end
 
   def prev_path
-    api_v1_timelines_tag_url params[:id], pagination_params(since_id: pagination_since_id)
+    api_v1_timelines_tag_url params[:id], pagination_params(min_id: pagination_since_id)
   end
 
   def pagination_max_id
diff --git a/app/controllers/api/web/embeds_controller.rb b/app/controllers/api/web/embeds_controller.rb
index 987290a14ce5be54b1fc3aa942598c79a34d1286..6231733b71aa101f395a7e8b80f7ea684d488b3c 100644
--- a/app/controllers/api/web/embeds_controller.rb
+++ b/app/controllers/api/web/embeds_controller.rb
@@ -10,6 +10,7 @@ class Api::Web::EmbedsController < Api::Web::BaseController
     render json: status, serializer: OEmbedSerializer, width: 400
   rescue ActiveRecord::RecordNotFound
     oembed = FetchOEmbedService.new.call(params[:url])
+    oembed[:html] = Formatter.instance.sanitize(oembed[:html], Sanitize::Config::MASTODON_OEMBED) if oembed[:html].present?
 
     if oembed
       render json: oembed
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 29ba6cad616b1a5902fcd2f61e3510dfef00a04b..b54e7b008eeb06283bb7b7a94e39ddb6a4dbaf97 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base
   rescue_from Mastodon::NotPermittedError, with: :forbidden
 
   before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
-  before_action :check_suspension, if: :user_signed_in?
+  before_action :check_user_permissions, if: :user_signed_in?
 
   def raise_not_found
     raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}"
@@ -48,8 +48,8 @@ class ApplicationController < ActionController::Base
     forbidden unless current_user&.staff?
   end
 
-  def check_suspension
-    forbidden if current_user.account.suspended?
+  def check_user_permissions
+    forbidden if current_user.disabled? || current_user.account.suspended?
   end
 
   def after_sign_out_path_for(_resource_or_scope)
@@ -58,6 +58,10 @@ class ApplicationController < ActionController::Base
 
   protected
 
+  def truthy_param?(key)
+    ActiveModel::Type::Boolean.new.cast(params[key])
+  end
+
   def forbidden
     respond_with_error(403)
   end
@@ -95,7 +99,7 @@ class ApplicationController < ActionController::Base
   end
 
   def current_theme
-    return Setting.default_settings['theme'] unless Themes.instance.names.include? current_user&.setting_theme
+    return Setting.theme unless Themes.instance.names.include? current_user&.setting_theme
     current_user.setting_theme
   end
 
@@ -103,29 +107,26 @@ class ApplicationController < ActionController::Base
     return raw unless klass.respond_to?(:with_includes)
 
     raw                    = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation)
-    uncached_ids           = []
-    cached_keys_with_value = Rails.cache.read_multi(*raw.map(&:cache_key))
-
-    raw.each do |item|
-      uncached_ids << item.id unless cached_keys_with_value.key?(item.cache_key)
-    end
+    cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id)
+    uncached_ids           = raw.map(&:id) - cached_keys_with_value.keys
 
     klass.reload_stale_associations!(cached_keys_with_value.values) if klass.respond_to?(:reload_stale_associations!)
 
     unless uncached_ids.empty?
-      uncached = klass.where(id: uncached_ids).with_includes.map { |item| [item.id, item] }.to_h
+      uncached = klass.where(id: uncached_ids).with_includes.each_with_object({}) { |item, h| h[item.id] = item }
 
       uncached.each_value do |item|
-        Rails.cache.write(item.cache_key, item)
+        Rails.cache.write(item, item)
       end
     end
 
-    raw.map { |item| cached_keys_with_value[item.cache_key] || uncached[item.id] }.compact
+    raw.map { |item| cached_keys_with_value[item.id] || uncached[item.id] }.compact
   end
 
   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
@@ -135,7 +136,6 @@ class ApplicationController < ActionController::Base
 
   def render_cached_json(cache_key, **options)
     options[:expires_in] ||= 3.minutes
-    cache_key              = cache_key.join(':') if cache_key.is_a?(Enumerable)
     cache_public           = options.key?(:public) ? options.delete(:public) : true
     content_type           = options.delete(:content_type) || 'application/json'
 
diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb
index 068e71cada69c03012bdd1cefbef079b72af92e2..c28c7471c0d1636b5f14f59400c4d8746a8d262b 100644
--- a/app/controllers/auth/confirmations_controller.rb
+++ b/app/controllers/auth/confirmations_controller.rb
@@ -3,11 +3,12 @@
 class Auth::ConfirmationsController < Devise::ConfirmationsController
   layout 'auth'
 
+  before_action :set_body_classes
   before_action :set_user, only: [:finish_signup]
 
-  # GET/PATCH /users/:id/finish_signup
   def finish_signup
     return unless request.patch? && params[:user]
+
     if @user.update(user_params)
       @user.skip_reconfirmation!
       bypass_sign_in(@user)
@@ -23,7 +24,19 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
     @user = current_user
   end
 
+  def set_body_classes
+    @body_classes = 'lighter'
+  end
+
   def user_params
     params.require(:user).permit(:email)
   end
+
+  def after_confirmation_path_for(_resource_name, user)
+    if user.created_by_application && truthy_param?(:redirect_to_app)
+      user.created_by_application.redirect_uri
+    else
+      super
+    end
+  end
 end
diff --git a/app/controllers/auth/passwords_controller.rb b/app/controllers/auth/passwords_controller.rb
index 171b997dc486f62c6e002c7f838cb3343f602316..34b98da53bfc1cb52120009d1f39d403cba6f3e9 100644
--- a/app/controllers/auth/passwords_controller.rb
+++ b/app/controllers/auth/passwords_controller.rb
@@ -2,6 +2,7 @@
 
 class Auth::PasswordsController < Devise::PasswordsController
   before_action :check_validity_of_reset_password_token, only: :edit
+  before_action :set_body_classes
 
   layout 'auth'
 
@@ -14,6 +15,10 @@ class Auth::PasswordsController < Devise::PasswordsController
     end
   end
 
+  def set_body_classes
+    @body_classes = 'lighter'
+  end
+
   def reset_password_token_is_valid?
     resource_class.with_reset_password_token(params[:reset_password_token]).present?
   end
diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb
index 58961554e6b7fe46cc86b2725eed7c6d823f49ce..f2a832542fe5489dc8cce2e1670bd054d9071c5c 100644
--- a/app/controllers/auth/registrations_controller.rb
+++ b/app/controllers/auth/registrations_controller.rb
@@ -8,6 +8,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
   before_action :configure_sign_up_params, only: [:create]
   before_action :set_sessions, only: [:edit, :update]
   before_action :set_instance_presenter, only: [:new, :create, :update]
+  before_action :set_body_classes, only: [:new, :create, :edit, :update]
 
   def destroy
     not_found
@@ -25,6 +26,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
 
     resource.locale      = I18n.locale
     resource.invite_code = params[:invite_code] if resource.invite_code.blank?
+    resource.agreement   = true
 
     resource.build_account if resource.account.nil?
   end
@@ -79,6 +81,10 @@ class Auth::RegistrationsController < Devise::RegistrationsController
     @instance_presenter = InstancePresenter.new
   end
 
+  def set_body_classes
+    @body_classes = %w(edit update).include?(action_name) ? 'admin' : 'lighter'
+  end
+
   def set_invite
     @invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil
   end
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index c1ebe760c5d90814cb5ac2b64c938ed55ebeee21..fb8615c3134dc5b6db94ddf648b7f7bda1717340 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -6,9 +6,10 @@ class Auth::SessionsController < Devise::SessionsController
   layout 'auth'
 
   skip_before_action :require_no_authentication, only: [:create]
-  skip_before_action :check_suspension, only: [:destroy]
+  skip_before_action :check_user_permissions, only: [:destroy]
   prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
   before_action :set_instance_presenter, only: [:new]
+  before_action :set_body_classes
 
   def new
     Devise.omniauth_configs.each do |provider, config|
@@ -26,8 +27,10 @@ class Auth::SessionsController < Devise::SessionsController
   end
 
   def destroy
+    tmp_stored_location = stored_location_for(:user)
     super
     flash.delete(:notice)
+    store_location_for(:user, tmp_stored_location) if continue_after?
   end
 
   protected
@@ -109,6 +112,10 @@ class Auth::SessionsController < Devise::SessionsController
     @instance_presenter = InstancePresenter.new
   end
 
+  def set_body_classes
+    @body_classes = 'lighter'
+  end
+
   def home_paths(resource)
     paths = [about_path]
     if single_user_mode? && resource.is_a?(User)
@@ -116,4 +123,8 @@ class Auth::SessionsController < Devise::SessionsController
     end
     paths
   end
+
+  def continue_after?
+    truthy_param?(:continue)
+  end
 end
diff --git a/app/controllers/authorize_follows_controller.rb b/app/controllers/authorize_follows_controller.rb
deleted file mode 100644
index 775d5f23fb32dfd1b337fe9f500e5324f27c0d1a..0000000000000000000000000000000000000000
--- a/app/controllers/authorize_follows_controller.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-class AuthorizeFollowsController < ApplicationController
-  layout 'modal'
-
-  before_action :authenticate_user!
-  before_action :set_body_classes
-
-  def show
-    @account = located_account || render(:error)
-  end
-
-  def create
-    @account = follow_attempt.try(:target_account)
-
-    if @account.nil?
-      render :error
-    else
-      render :success
-    end
-  rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
-    render :error
-  end
-
-  private
-
-  def follow_attempt
-    FollowService.new.call(current_account, acct_without_prefix)
-  end
-
-  def located_account
-    if acct_param_is_url?
-      account_from_remote_fetch
-    else
-      account_from_remote_follow
-    end
-  end
-
-  def account_from_remote_fetch
-    FetchRemoteAccountService.new.call(acct_without_prefix)
-  end
-
-  def account_from_remote_follow
-    ResolveAccountService.new.call(acct_without_prefix)
-  end
-
-  def acct_param_is_url?
-    parsed_uri.path && %w(http https).include?(parsed_uri.scheme)
-  end
-
-  def parsed_uri
-    Addressable::URI.parse(acct_without_prefix).normalize
-  end
-
-  def acct_without_prefix
-    acct_params.gsub(/\Aacct:/, '')
-  end
-
-  def acct_params
-    params.fetch(:acct, '')
-  end
-
-  def set_body_classes
-    @body_classes = 'modal-layout'
-  end
-end
diff --git a/app/controllers/authorize_interactions_controller.rb b/app/controllers/authorize_interactions_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e27366ea363880921f4c21d6fe1f1a18ea330f4c
--- /dev/null
+++ b/app/controllers/authorize_interactions_controller.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+class AuthorizeInteractionsController < ApplicationController
+  include Authorization
+
+  layout 'modal'
+
+  before_action :authenticate_user!
+  before_action :set_body_classes
+  before_action :set_resource
+
+  def show
+    if @resource.is_a?(Account)
+      render :show
+    elsif @resource.is_a?(Status)
+      redirect_to web_url("statuses/#{@resource.id}")
+    else
+      render :error
+    end
+  end
+
+  def create
+    if @resource.is_a?(Account) && FollowService.new.call(current_account, @resource)
+      render :success
+    else
+      render :error
+    end
+  rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
+    render :error
+  end
+
+  private
+
+  def set_resource
+    @resource = located_resource || render(:error)
+    authorize(@resource, :show?) if @resource.is_a?(Status)
+  end
+
+  def located_resource
+    if uri_param_is_url?
+      ResolveURLService.new.call(uri_param)
+    else
+      account_from_remote_follow
+    end
+  end
+
+  def account_from_remote_follow
+    ResolveAccountService.new.call(uri_param)
+  end
+
+  def uri_param_is_url?
+    parsed_uri.path && %w(http https).include?(parsed_uri.scheme)
+  end
+
+  def parsed_uri
+    Addressable::URI.parse(uri_param).normalize
+  end
+
+  def uri_param
+    params[:uri] || params.fetch(:acct, '').gsub(/\Aacct:/, '')
+  end
+
+  def set_body_classes
+    @body_classes = 'modal-layout'
+  end
+end
diff --git a/app/controllers/concerns/account_controller_concern.rb b/app/controllers/concerns/account_controller_concern.rb
index 5b9981aa26ef80f416660e6fdfdc69d69886d772..6c27ef330b90b8a40499d1a84ba5edb4373f82ed 100644
--- a/app/controllers/concerns/account_controller_concern.rb
+++ b/app/controllers/concerns/account_controller_concern.rb
@@ -8,6 +8,7 @@ module AccountControllerConcern
   included do
     layout 'public'
     before_action :set_account
+    before_action :set_instance_presenter
     before_action :set_link_headers
     before_action :check_account_suspension
   end
@@ -18,6 +19,10 @@ module AccountControllerConcern
     @account = Account.find_local!(params[:account_username])
   end
 
+  def set_instance_presenter
+    @instance_presenter = InstancePresenter.new
+  end
+
   def set_link_headers
     response.headers['Link'] = LinkHeader.new(
       [
diff --git a/app/controllers/concerns/remote_account_controller_concern.rb b/app/controllers/concerns/remote_account_controller_concern.rb
deleted file mode 100644
index e1791064244303d121eba26f3883a7d199500c8b..0000000000000000000000000000000000000000
--- a/app/controllers/concerns/remote_account_controller_concern.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-module RemoteAccountControllerConcern
-  extend ActiveSupport::Concern
-
-  included do
-    layout 'public'
-    before_action :set_account
-    before_action :check_account_suspension
-  end
-
-  private
-
-  def set_account
-    @account = Account.find_remote!(params[:acct])
-  end
-
-  def check_account_suspension
-    gone if @account.suspended?
-  end
-end
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index 4d77fa43241963d32074b93e6dcee2268fd5eb5c..91566c4fad95ca2401af4022047fd1ea579cdc11 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -22,6 +22,12 @@ module SignatureVerification
       return
     end
 
+    if request.headers['Date'].present? && !matches_time_window?
+      @signature_verification_failure_reason = 'Signed request date outside acceptable time window'
+      @signed_request_account = nil
+      return
+    end
+
     raw_signature    = request.headers['Signature']
     signature_params = {}
 
@@ -37,7 +43,13 @@ module SignatureVerification
       return
     end
 
-    account = account_from_key_id(signature_params['keyId'])
+    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
 
     if account.nil?
       @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
@@ -48,23 +60,26 @@ module SignatureVerification
     signature             = Base64.decode64(signature_params['signature'])
     compare_signed_string = build_signed_string(signature_params['headers'])
 
-    if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
-      @signed_request_account = account
-      @signed_request_account
-    elsif account.possibly_stale?
-      account = account.refresh!
+    return account unless verify_signature(account, signature, compare_signed_string).nil?
 
-      if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
-        @signed_request_account = account
-        @signed_request_account
-      else
-        @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
-        @signed_request_account = nil
-      end
-    else
-      @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
+    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
+
+    if account.nil?
+      @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
       @signed_request_account = nil
+      return
     end
+
+    return account unless verify_signature(account, signature, compare_signed_string).nil?
+
+    @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
+    @signed_request_account = nil
   end
 
   def request_body
@@ -73,10 +88,19 @@ module SignatureVerification
 
   private
 
+  def verify_signature(account, signature, compare_signed_string)
+    if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
+      @signed_request_account = account
+      @signed_request_account
+    end
+  rescue OpenSSL::PKey::RSAError
+    nil
+  end
+
   def build_signed_string(signed_headers)
     signed_headers = 'date' if signed_headers.blank?
 
-    signed_headers.split(' ').map do |signed_header|
+    signed_headers.downcase.split(' ').map do |signed_header|
       if signed_header == Request::REQUEST_TARGET
         "#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
       elsif signed_header == 'digest'
@@ -89,12 +113,12 @@ module SignatureVerification
 
   def matches_time_window?
     begin
-      time_sent = DateTime.httpdate(request.headers['Date'])
+      time_sent = Time.httpdate(request.headers['Date'])
     rescue ArgumentError
       return false
     end
 
-    (Time.now.utc - time_sent).abs <= 30
+    (Time.now.utc - time_sent).abs <= 12.hours
   end
 
   def body_digest
@@ -119,4 +143,9 @@ module SignatureVerification
       account
     end
   end
+
+  def account_refresh_key(account)
+    return if account.local? || !account.activitypub?
+    ActivityPub::FetchRemoteAccountService.new.call(account.uri, only_key: true)
+  end
 end
diff --git a/app/controllers/custom_css_controller.rb b/app/controllers/custom_css_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..31e501609d809738ebf56af4166fda4b72a64947
--- /dev/null
+++ b/app/controllers/custom_css_controller.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class CustomCssController < ApplicationController
+  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
new file mode 100644
index 0000000000000000000000000000000000000000..ff7ff4a428154fb8b178689a73339d47f8164155
--- /dev/null
+++ b/app/controllers/directories_controller.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+class DirectoriesController < ApplicationController
+  layout 'public'
+
+  before_action :check_enabled
+  before_action :set_instance_presenter
+  before_action :set_tag, only: :show
+  before_action :set_tags
+  before_action :set_accounts
+
+  def index
+    render :index
+  end
+
+  def show
+    render :index
+  end
+
+  private
+
+  def check_enabled
+    return not_found unless Setting.profile_directory
+  end
+
+  def set_tag
+    @tag = Tag.discoverable.find_by!(name: params[:id].downcase)
+  end
+
+  def set_tags
+    @tags = Tag.discoverable.limit(30).reject { |tag| tag.cached_sample_accounts.empty? }
+  end
+
+  def set_accounts
+    @accounts = Account.discoverable.page(params[:page]).per(40).tap do |query|
+      query.merge!(Account.tagged_with(@tag.id)) if @tag
+    end
+  end
+
+  def set_instance_presenter
+    @instance_presenter = InstancePresenter.new
+  end
+end
diff --git a/app/controllers/emojis_controller.rb b/app/controllers/emojis_controller.rb
index c9725ccc0d2d26a384a84dd4ed06e72050eb37d2..5d306e6005f1ee8eb244f09b9709b2a0821a6d23 100644
--- a/app/controllers/emojis_controller.rb
+++ b/app/controllers/emojis_controller.rb
@@ -9,7 +9,7 @@ class EmojisController < ApplicationController
       format.json do
         skip_session!
 
-        render_cached_json(['activitypub', 'emoji', @emoji.cache_key], content_type: 'application/activity+json') do
+        render_cached_json(['activitypub', 'emoji', @emoji], content_type: 'application/activity+json') do
           ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter)
         end
       end
diff --git a/app/controllers/filters_controller.rb b/app/controllers/filters_controller.rb
index 03403a1ba104233a200cc9d36221158bfba9905c..d2e0fb73907f243bbae10be4b3bd6e2ce20c74ec 100644
--- a/app/controllers/filters_controller.rb
+++ b/app/controllers/filters_controller.rb
@@ -7,6 +7,7 @@ class FiltersController < ApplicationController
 
   before_action :set_filters, only: :index
   before_action :set_filter, only: [:edit, :update, :destroy]
+  before_action :set_body_classes
 
   def index
     @filters = current_account.custom_filters
@@ -52,6 +53,10 @@ class FiltersController < ApplicationController
   end
 
   def resource_params
-    params.require(:custom_filter).permit(:phrase, :expires_in, :irreversible, context: [])
+    params.require(:custom_filter).permit(:phrase, :expires_in, :irreversible, :whole_word, context: [])
+  end
+
+  def set_body_classes
+    @body_classes = 'admin'
   end
 end
diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb
index b71424107bc30df13944ed50109057e66d0a8834..b5d6460f9fc1a2dfca8a904a661a5db55b924e89 100644
--- a/app/controllers/home_controller.rb
+++ b/app/controllers/home_controller.rb
@@ -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.first)
+      short_account_path(Account.local.where(suspended: false).first)
     else
       about_path
     end
diff --git a/app/controllers/intents_controller.rb b/app/controllers/intents_controller.rb
index 56129d69aff4bfbd78825536743b7c578ababdf1..9f41cf48ac3183fe49414c6aa96418608e5e86e0 100644
--- a/app/controllers/intents_controller.rb
+++ b/app/controllers/intents_controller.rb
@@ -8,7 +8,7 @@ class IntentsController < ApplicationController
     if uri.scheme == 'web+mastodon'
       case uri.host
       when 'follow'
-        return redirect_to authorize_follow_path(acct: uri.query_values['uri'].gsub(/\Aacct:/, ''))
+        return redirect_to authorize_interaction_path(uri: uri.query_values['uri'].gsub(/\Aacct:/, ''))
       when 'share'
         return redirect_to share_path(text: uri.query_values['text'])
       end
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index 5c30313f498a0614bff920a06d61e8b5e73c021a..fdb3a0962a2ac4f53f7ec443be4ea60c3e33c771 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -6,6 +6,7 @@ class InvitesController < ApplicationController
   layout 'admin'
 
   before_action :authenticate_user!
+  before_action :set_body_classes
 
   def index
     authorize :invite, :create?
@@ -38,10 +39,14 @@ class InvitesController < ApplicationController
   private
 
   def invites
-    Invite.where(user: current_user)
+    Invite.where(user: current_user).order(id: :desc)
   end
 
   def resource_params
     params.require(:invite).permit(:max_uses, :expires_in, :autofollow)
   end
+
+  def set_body_classes
+    @body_classes = 'admin'
+  end
 end
diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb
index 88c7232dd848b5e704c86222771fd75e2d65f629..8e1624ce1b449b627f227df85a616c8f021dbb81 100644
--- a/app/controllers/media_controller.rb
+++ b/app/controllers/media_controller.rb
@@ -6,12 +6,17 @@ class MediaController < ApplicationController
   before_action :set_media_attachment
   before_action :verify_permitted_status!
 
+  content_security_policy only: :player do |p|
+    p.frame_ancestors(false)
+  end
+
   def show
     redirect_to @media_attachment.file.url(:original)
   end
 
   def player
     @body_classes = 'player'
+    response.headers['X-Frame-Options'] = 'ALLOWALL'
     raise ActiveRecord::RecordNotFound unless @media_attachment.video? || @media_attachment.gifv?
   end
 
diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb
index e9cdf9fa8afbe692c76bb0f52ce37ad2df658517..cebbdc4d08b02bb1f31dc4bf5568a1aa22882624 100644
--- a/app/controllers/oauth/authorizations_controller.rb
+++ b/app/controllers/oauth/authorizations_controller.rb
@@ -13,4 +13,18 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
   def store_current_location
     store_location_for(:user, request.url)
   end
+
+  def render_success
+    if skip_authorization? || (matching_token? && !truthy_param?('force_login'))
+      redirect_or_render authorize_response
+    elsif Doorkeeper.configuration.api_only
+      render json: pre_auth
+    else
+      render :new
+    end
+  end
+
+  def truthy_param?(key)
+    ActiveModel::Type::Boolean.new.cast(params[key])
+  end
 end
diff --git a/app/controllers/remote_follow_controller.rb b/app/controllers/remote_follow_controller.rb
index cd61fd7639a410b828a21c03cbd16e9feee23568..8ba331cd16ca51e777c218b5f52b670c2aa2c866 100644
--- a/app/controllers/remote_follow_controller.rb
+++ b/app/controllers/remote_follow_controller.rb
@@ -42,5 +42,6 @@ class RemoteFollowController < ApplicationController
 
   def set_body_classes
     @body_classes = 'modal-layout'
+    @hide_header  = true
   end
 end
diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cc6993c52b22236dd4b95a4aa698c5e5527e8eed
--- /dev/null
+++ b/app/controllers/remote_interaction_controller.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+class RemoteInteractionController < ApplicationController
+  include Authorization
+
+  layout 'modal'
+
+  before_action :set_interaction_type
+  before_action :set_status
+  before_action :set_body_classes
+
+  def new
+    @remote_follow = RemoteFollow.new(session_params)
+  end
+
+  def create
+    @remote_follow = RemoteFollow.new(resource_params)
+
+    if @remote_follow.valid?
+      session[:remote_follow] = @remote_follow.acct
+      redirect_to @remote_follow.interact_address_for(@status)
+    else
+      render :new
+    end
+  end
+
+  private
+
+  def resource_params
+    params.require(:remote_follow).permit(:acct)
+  end
+
+  def session_params
+    { acct: session[:remote_follow] }
+  end
+
+  def set_status
+    @status = Status.find(params[:id])
+    authorize @status, :show?
+  rescue Mastodon::NotPermittedError
+    # Reraise in order to get a 404
+    raise ActiveRecord::RecordNotFound
+  end
+
+  def set_body_classes
+    @body_classes = 'modal-layout'
+    @hide_header  = true
+  end
+
+  def set_interaction_type
+    @interaction_type = %w(reply reblog favourite).include?(params[:type]) ? params[:type] : 'reply'
+  end
+end
diff --git a/app/controllers/settings/applications_controller.rb b/app/controllers/settings/applications_controller.rb
index 2a4962311573c55e379c0d2e0aa8b3b28bce8303..ed3f82a8e06e693e8107c0fbdf2211d7ec48a3a0 100644
--- a/app/controllers/settings/applications_controller.rb
+++ b/app/controllers/settings/applications_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::ApplicationsController < ApplicationController
+class Settings::ApplicationsController < Settings::BaseController
   layout 'admin'
 
   before_action :authenticate_user!
diff --git a/app/controllers/settings/base_controller.rb b/app/controllers/settings/base_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9bb14afa2d65d6be17ed665c26c675ef8aa5f717
--- /dev/null
+++ b/app/controllers/settings/base_controller.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class Settings::BaseController < ApplicationController
+  before_action :set_body_classes
+
+  private
+
+  def set_body_classes
+    @body_classes = 'admin'
+  end
+end
diff --git a/app/controllers/settings/deletes_controller.rb b/app/controllers/settings/deletes_controller.rb
index 80002b995e58a20eff26ee9257b3fc32957aa406..dd19aadf636b6fd35541efdc4552ccf0e6b66bd9 100644
--- a/app/controllers/settings/deletes_controller.rb
+++ b/app/controllers/settings/deletes_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::DeletesController < ApplicationController
+class Settings::DeletesController < Settings::BaseController
   layout 'admin'
 
   before_action :check_enabled_deletion
diff --git a/app/controllers/settings/exports/blocked_domains_controller.rb b/app/controllers/settings/exports/blocked_domains_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6676ce340148f9488398f78612d311f59bec2c29
--- /dev/null
+++ b/app/controllers/settings/exports/blocked_domains_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Settings
+  module Exports
+    class BlockedDomainsController < ApplicationController
+      include ExportControllerConcern
+
+      def index
+        send_export_file
+      end
+
+      private
+
+      def export_data
+        @export.to_blocked_domains_csv
+      end
+    end
+  end
+end
diff --git a/app/controllers/settings/exports/lists_controller.rb b/app/controllers/settings/exports/lists_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cf5a9de44b33bd3bd3c1cea91fbc4a79a345a9c1
--- /dev/null
+++ b/app/controllers/settings/exports/lists_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Settings
+  module Exports
+    class ListsController < ApplicationController
+      include ExportControllerConcern
+
+      def index
+        send_export_file
+      end
+
+      private
+
+      def export_data
+        @export.to_lists_csv
+      end
+    end
+  end
+end
diff --git a/app/controllers/settings/exports_controller.rb b/app/controllers/settings/exports_controller.rb
index 869e11d3bf601782e24bc534d312a95486abb574..0135f21890dd0e81bd0bbd9290b669603e1388f1 100644
--- a/app/controllers/settings/exports_controller.rb
+++ b/app/controllers/settings/exports_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::ExportsController < ApplicationController
+class Settings::ExportsController < Settings::BaseController
   include Authorization
 
   layout 'admin'
diff --git a/app/controllers/settings/follower_domains_controller.rb b/app/controllers/settings/follower_domains_controller.rb
index a128bd1361f7f89785660805b500657d14a8b9f0..ce8ec985d62b5772a09f0ce3ee058b4b1606fd35 100644
--- a/app/controllers/settings/follower_domains_controller.rb
+++ b/app/controllers/settings/follower_domains_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::FollowerDomainsController < ApplicationController
+class Settings::FollowerDomainsController < Settings::BaseController
   layout 'admin'
 
   before_action :authenticate_user!
diff --git a/app/controllers/settings/imports_controller.rb b/app/controllers/settings/imports_controller.rb
index 0db13d1ca640586d8970a476ad352b996c96d762..38f2e39c1d179ceb3c357d29f0f313c8bb43e646 100644
--- a/app/controllers/settings/imports_controller.rb
+++ b/app/controllers/settings/imports_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::ImportsController < ApplicationController
+class Settings::ImportsController < Settings::BaseController
   layout 'admin'
 
   before_action :authenticate_user!
diff --git a/app/controllers/settings/migrations_controller.rb b/app/controllers/settings/migrations_controller.rb
index bc6436b87aff6f6967350eb8013f7866be17d45e..59eb48779c142bd274d138be83936661b74042e7 100644
--- a/app/controllers/settings/migrations_controller.rb
+++ b/app/controllers/settings/migrations_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::MigrationsController < ApplicationController
+class Settings::MigrationsController < Settings::BaseController
   layout 'admin'
 
   before_action :authenticate_user!
diff --git a/app/controllers/settings/notifications_controller.rb b/app/controllers/settings/notifications_controller.rb
index ce2530c54163ac8096e0144cd52097ff66222fd1..da8a03d96491d815c2844ed4fb8ef74c8dda2f94 100644
--- a/app/controllers/settings/notifications_controller.rb
+++ b/app/controllers/settings/notifications_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::NotificationsController < ApplicationController
+class Settings::NotificationsController < Settings::BaseController
   layout 'admin'
 
   before_action :authenticate_user!
@@ -25,7 +25,7 @@ class Settings::NotificationsController < ApplicationController
 
   def user_settings_params
     params.require(:user).permit(
-      notification_emails: %i(follow follow_request reblog favourite mention digest),
+      notification_emails: %i(follow follow_request reblog favourite mention digest report),
       interactions: %i(must_be_follower must_be_following must_be_following_dm)
     )
   end
diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index e2cb131671d3e3ab70b3867aa093f601338142c6..41df3bde2fcda328a4ef003543aca4ba602486c3 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::PreferencesController < ApplicationController
+class Settings::PreferencesController < Settings::BaseController
   layout 'admin'
 
   before_action :authenticate_user!
@@ -40,13 +40,15 @@ class Settings::PreferencesController < ApplicationController
       :setting_boost_modal,
       :setting_delete_modal,
       :setting_auto_play_gif,
-      :setting_display_sensitive_media,
+      :setting_display_media,
+      :setting_expand_spoilers,
       :setting_reduce_motion,
       :setting_system_font_ui,
       :setting_noindex,
       :setting_theme,
       :setting_hide_network,
-      notification_emails: %i(follow follow_request reblog favourite mention digest),
+      :setting_aggregate_reblogs,
+      notification_emails: %i(follow follow_request reblog favourite mention digest report),
       interactions: %i(must_be_follower must_be_following)
     )
   end
diff --git a/app/controllers/settings/profiles_controller.rb b/app/controllers/settings/profiles_controller.rb
index fe265c81d29250a9c9d404a52b69a2417f0e702a..db9081fdf012a7029456c5c51ff3b1e072ad3ea1 100644
--- a/app/controllers/settings/profiles_controller.rb
+++ b/app/controllers/settings/profiles_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::ProfilesController < ApplicationController
+class Settings::ProfilesController < Settings::BaseController
   include ObfuscateFilename
 
   layout 'admin'
@@ -28,7 +28,7 @@ class Settings::ProfilesController < ApplicationController
   private
 
   def account_params
-    params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, fields_attributes: [:name, :value])
+    params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, fields_attributes: [:name, :value])
   end
 
   def set_account
diff --git a/app/controllers/settings/sessions_controller.rb b/app/controllers/settings/sessions_controller.rb
index 0da1b027b8e439395e7069aa0569526453d74dea..11b150ffd3ae0f5da9038e717eb9353f15740824 100644
--- a/app/controllers/settings/sessions_controller.rb
+++ b/app/controllers/settings/sessions_controller.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class Settings::SessionsController < ApplicationController
+class Settings::SessionsController < Settings::BaseController
   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 8d534960d4bf0c86fc23dc062ee940514c72bae1..d87117a50a846c3a31023db36c2ef47cc63020a4 100644
--- a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb
+++ b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb
@@ -2,7 +2,7 @@
 
 module Settings
   module TwoFactorAuthentication
-    class ConfirmationsController < ApplicationController
+    class ConfirmationsController < BaseController
       layout 'admin'
 
       before_action :authenticate_user!
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 e591e9502d9025d2600d6f93f11e4f7b5ae57a47..c78166c6542e722b09091f2338c272f62145cb10 100644
--- a/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb
+++ b/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb
@@ -2,7 +2,7 @@
 
 module Settings
   module TwoFactorAuthentication
-    class RecoveryCodesController < ApplicationController
+    class RecoveryCodesController < BaseController
       layout 'admin'
 
       before_action :authenticate_user!
diff --git a/app/controllers/settings/two_factor_authentications_controller.rb b/app/controllers/settings/two_factor_authentications_controller.rb
index 863cc7351b7e20fe3ba8568e0d344a9b0315dbe9..e12c4307468653c19c5a0c5e8c7cd5dc6d2792f5 100644
--- a/app/controllers/settings/two_factor_authentications_controller.rb
+++ b/app/controllers/settings/two_factor_authentications_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module Settings
-  class TwoFactorAuthenticationsController < ApplicationController
+  class TwoFactorAuthenticationsController < BaseController
     layout 'admin'
 
     before_action :authenticate_user!
diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb
index b8534182291c04901d766e06149b29a2e4d02fb2..15d59fd89345cdc408377586f166a6262b5a5455 100644
--- a/app/controllers/statuses_controller.rb
+++ b/app/controllers/statuses_controller.rb
@@ -12,15 +12,22 @@ class StatusesController < ApplicationController
 
   before_action :set_account
   before_action :set_status
+  before_action :set_instance_presenter
   before_action :set_link_headers
   before_action :check_account_suspension
   before_action :redirect_to_original, only: [:show]
   before_action :set_referrer_policy_header, only: [:show]
   before_action :set_cache_headers
 
+  content_security_policy only: :embed do |p|
+    p.frame_ancestors(false)
+  end
+
   def show
     respond_to do |format|
       format.html do
+        @body_classes = 'with-modals'
+
         set_ancestors
         set_descendants
 
@@ -30,7 +37,7 @@ class StatusesController < ApplicationController
       format.json do
         skip_session! unless @stream_entry.hidden?
 
-        render_cached_json(['activitypub', 'note', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
+        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
       end
@@ -40,7 +47,7 @@ class StatusesController < ApplicationController
   def activity
     skip_session!
 
-    render_cached_json(['activitypub', 'activity', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
+    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
   end
@@ -51,18 +58,20 @@ class StatusesController < ApplicationController
     skip_session!
     expires_in 180, public: true
     response.headers['X-Frame-Options'] = 'ALLOWALL'
+    @autoplay = ActiveModel::Type::Boolean.new.cast(params[:autoplay])
 
     render 'stream_entries/embed', layout: 'embedded'
   end
 
   private
 
-  def create_descendant_thread(depth, statuses)
+  def create_descendant_thread(starting_depth, statuses)
+    depth = starting_depth + statuses.size
     if depth < DESCENDANTS_DEPTH_LIMIT
-      { statuses: statuses }
+      { statuses: statuses, starting_depth: starting_depth }
     else
       next_status = statuses.pop
-      { statuses: statuses, next_status: next_status }
+      { statuses: statuses, starting_depth: starting_depth, next_status: next_status }
     end
   end
 
@@ -93,16 +102,19 @@ class StatusesController < ApplicationController
     @descendant_threads = []
 
     if descendants.present?
-      statuses = [descendants.first]
-      depth    = 1
+      statuses       = [descendants.first]
+      starting_depth = 0
 
       descendants.drop(1).each_with_index do |descendant, index|
         if descendants[index].id == descendant.in_reply_to_id
-          depth += 1
           statuses << descendant
         else
-          @descendant_threads << create_descendant_thread(depth, statuses)
+          @descendant_threads << create_descendant_thread(starting_depth, statuses)
+
+          # The thread is broken, assume it's a reply to the root status
+          starting_depth = 0
 
+          # ... unless we can find its ancestor in one of the already-processed threads
           @descendant_threads.reverse_each do |descendant_thread|
             statuses = descendant_thread[:statuses]
 
@@ -111,18 +123,16 @@ class StatusesController < ApplicationController
             end
 
             if index.present?
-              depth += index - statuses.size
+              starting_depth = descendant_thread[:starting_depth] + index + 1
               break
             end
-
-            depth -= statuses.size
           end
 
           statuses = [descendant]
         end
       end
 
-      @descendant_threads << create_descendant_thread(depth, statuses)
+      @descendant_threads << create_descendant_thread(starting_depth, statuses)
     end
 
     @max_descendant_thread_id = @descendant_threads.pop[:statuses].first.id if descendants.size >= DESCENDANTS_LIMIT
@@ -148,6 +158,10 @@ class StatusesController < ApplicationController
     raise ActiveRecord::RecordNotFound
   end
 
+  def set_instance_presenter
+    @instance_presenter = InstancePresenter.new
+  end
+
   def check_account_suspension
     gone if @account.suspended?
   end
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index 014a5c9b8dd64be7ab48e6a84d43461e9476cd97..4694c823a42c80968de3351f1f8b90c35a0c0160 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -3,6 +3,8 @@
 class TagsController < ApplicationController
   PAGE_SIZE = 20
 
+  layout 'public'
+
   before_action :set_body_classes
   before_action :set_instance_presenter
 
@@ -16,14 +18,15 @@ class TagsController < ApplicationController
       end
 
       format.rss do
-        @statuses = Status.as_tag_timeline(@tag).limit(PAGE_SIZE)
+        @statuses = HashtagQueryService.new.call(@tag, params.slice(:any, :all, :none)).limit(PAGE_SIZE)
         @statuses = cache_collection(@statuses, Status)
 
         render xml: RSS::TagSerializer.render(@tag, @statuses)
       end
 
       format.json do
-        @statuses = Status.as_tag_timeline(@tag, 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,
@@ -37,7 +40,7 @@ class TagsController < ApplicationController
   private
 
   def set_body_classes
-    @body_classes = 'tag-body'
+    @body_classes = 'with-modals'
   end
 
   def set_instance_presenter
@@ -46,7 +49,7 @@ class TagsController < ApplicationController
 
   def collection_presenter
     ActivityPub::CollectionPresenter.new(
-      id: tag_url(@tag),
+      id: tag_url(@tag, params.slice(:any, :all, :none)),
       type: :ordered,
       size: @tag.statuses.count,
       items: @statuses.map { |s| ActivityPub::TagManager.instance.uri_for(s) }
diff --git a/app/helpers/admin/account_moderation_notes_helper.rb b/app/helpers/admin/account_moderation_notes_helper.rb
index 49e764cefd6512eff86d0d5ee217e36c64c2f3ba..40b2a5289224bec355be02624dcb8d44843f2394 100644
--- a/app/helpers/admin/account_moderation_notes_helper.rb
+++ b/app/helpers/admin/account_moderation_notes_helper.rb
@@ -2,7 +2,9 @@
 
 module Admin::AccountModerationNotesHelper
   def admin_account_link_to(account)
-    link_to admin_account_path(account.id), class: name_tag_classes(account) do
+    return if account.nil?
+
+    link_to admin_account_path(account.id), class: name_tag_classes(account), title: account.acct do
       safe_join([
                   image_tag(account.avatar.url, width: 15, height: 15, alt: display_name(account), class: 'avatar'),
                   content_tag(:span, account.acct, class: 'username'),
@@ -11,7 +13,9 @@ module Admin::AccountModerationNotesHelper
   end
 
   def admin_account_inline_link_to(account)
-    link_to admin_account_path(account.id), class: name_tag_classes(account, true) do
+    return if account.nil?
+
+    link_to admin_account_path(account.id), class: name_tag_classes(account, true), title: account.acct do
       content_tag(:span, account.acct, class: 'username')
     end
   end
@@ -20,7 +24,7 @@ module Admin::AccountModerationNotesHelper
 
   def name_tag_classes(account, inline = false)
     classes = [inline ? 'inline-name-tag' : 'name-tag']
-    classes << 'suspended' if account.suspended?
+    classes << 'suspended' if account.suspended? || (account.local? && account.user.nil?)
     classes.join(' ')
   end
 end
diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb
index 4c663211e718da0e12df68e4f0dfc0ce2cfd53ab..359d60b60e29484703be2fee8b72e24403deda09 100644
--- a/app/helpers/admin/action_logs_helper.rb
+++ b/app/helpers/admin/action_logs_helper.rb
@@ -23,6 +23,8 @@ module Admin::ActionLogsHelper
       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
 
@@ -33,8 +35,13 @@ module Admin::ActionLogsHelper
     when 'DomainBlock', 'EmailDomainBlock'
       link_to attributes['domain'], "https://#{attributes['domain']}"
     when 'Status'
-      tmp_status = Status.new(attributes)
-      link_to tmp_status.account&.acct || "##{tmp_status.account_id}", TagManager.instance.url_for(tmp_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
 
@@ -77,6 +84,8 @@ module Admin::ActionLogsHelper
       'envelope'
     when 'Status'
       'pencil'
+    when 'AccountWarning'
+      'warning'
     end
   end
 
@@ -88,7 +97,7 @@ module Admin::ActionLogsHelper
       opposite_verbs?(log) ? 'negative' : 'positive'
     when :update, :reset_password, :disable_2fa, :memorialize, :change_email
       'neutral'
-    when :demote, :silence, :disable, :suspend, :remove_avatar, :reopen
+    when :demote, :silence, :disable, :suspend, :remove_avatar, :remove_header, :reopen
       'negative'
     when :destroy
       opposite_verbs?(log) ? 'positive' : 'negative'
@@ -100,6 +109,6 @@ module Admin::ActionLogsHelper
   private
 
   def opposite_verbs?(log)
-    %w(DomainBlock EmailDomainBlock).include?(log.target_type)
+    %w(DomainBlock EmailDomainBlock AccountWarning).include?(log.target_type)
   end
 end
diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb
index 359c43d0e353b42357d5c2dd6f92dd4b64828f40..97beb587fce1496b4b0fb8c2e4882ba79304ad7f 100644
--- a/app/helpers/admin/filter_helper.rb
+++ b/app/helpers/admin/filter_helper.rb
@@ -1,12 +1,14 @@
 # frozen_string_literal: true
 
 module Admin::FilterHelper
-  ACCOUNT_FILTERS      = %i(local remote by_domain silenced suspended recent username display_name email ip staff).freeze
+  ACCOUNT_FILTERS      = %i(local remote by_domain active 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
 
-  FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS + INVITE_FILTER + CUSTOM_EMOJI_FILTERS
+  FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS + INVITE_FILTER + CUSTOM_EMOJI_FILTERS + TAGS_FILTERS + INSTANCES_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 327901e4e2d0e782080d6a511448cc45bc5c9fb0..5097a0953e84bf1a5d966ccb08ec96d7293588f1 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -7,8 +7,8 @@ module ApplicationHelper
     follow
   ).freeze
 
-  def active_nav_class(path)
-    current_page?(path) ? 'active' : ''
+  def active_nav_class(*paths)
+    paths.any? { |path| current_page?(path) } ? 'active' : ''
   end
 
   def active_link_to(label, path, **options)
@@ -27,11 +27,6 @@ module ApplicationHelper
     Setting.open_deletion
   end
 
-  def add_rtl_body_class(other_classes)
-    other_classes = "#{other_classes} rtl" if locale_direction == 'rtl'
-    other_classes
-  end
-
   def locale_direction
     if [:ar, :fa, :he].include?(I18n.locale)
       'rtl'
@@ -74,7 +69,36 @@ module ApplicationHelper
     tag(:meta, content: content, property: property)
   end
 
-  def react_component(name, props = {})
-    content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
+  def react_component(name, props = {}, &block)
+    if block.nil?
+      content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
+    else
+      content_tag(:div, data: { component: name.to_s.camelcase, props: Oj.dump(props) }, &block)
+    end
+  end
+
+  def body_classes
+    output = (@body_classes || '').split(' ')
+    output << "theme-#{current_theme.parameterize}"
+    output << 'system-font' if current_account&.user&.setting_system_font_ui
+    output << (current_account&.user&.setting_reduce_motion ? 'reduce-motion' : 'no-reduce-motion')
+    output << 'rtl' if locale_direction == 'rtl'
+    output.reject(&:blank?).join(' ')
+  end
+
+  def cdn_host
+    Rails.configuration.action_controller.asset_host
+  end
+
+  def cdn_host?
+    cdn_host.present?
+  end
+
+  def storage_host
+    "https://#{ENV['S3_ALIAS_HOST'].presence || ENV['S3_CLOUDFRONT_HOST']}"
+  end
+
+  def storage_host?
+    ENV['S3_ALIAS_HOST'].present? || ENV['S3_CLOUDFRONT_HOST'].present?
   end
 end
diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb
index d3c6b13a65ea0afbeb047e6464f9bd50f98821b0..9b3f1380b149b99d702e92cb5755f366f453859d 100644
--- a/app/helpers/home_helper.rb
+++ b/app/helpers/home_helper.rb
@@ -6,4 +6,54 @@ module HomeHelper
       locale: I18n.locale,
     }
   end
+
+  def account_link_to(account, button = '', size: 36, path: nil)
+    content_tag(:div, class: 'account') do
+      content_tag(:div, class: 'account__wrapper') do
+        section = if account.nil?
+                    content_tag(:div, class: 'account__display-name') do
+                      content_tag(:div, class: 'account__avatar-wrapper') do
+                        content_tag(:div, '', class: 'account__avatar', style: "width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px; background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)})")
+                      end +
+                        content_tag(:span, class: 'display-name') do
+                          content_tag(:strong, t('about.contact_missing')) +
+                            content_tag(:span, t('about.contact_unavailable'), class: 'display-name__account')
+                        end
+                    end
+                  else
+                    link_to(path || TagManager.instance.url_for(account), class: 'account__display-name') do
+                      content_tag(:div, class: 'account__avatar-wrapper') do
+                        content_tag(:div, '', class: 'account__avatar', style: "width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px; background-image: url(#{full_asset_url(current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url)})")
+                      end +
+                        content_tag(:span, class: 'display-name') do
+                          content_tag(:bdi) do
+                            content_tag(:strong, display_name(account, custom_emojify: true), class: 'display-name__html emojify')
+                          end +
+                            content_tag(:span, "@#{account.acct}", class: 'display-name__account')
+                        end
+                    end
+                  end
+
+        section + button
+      end
+    end
+  end
+
+  def obscured_counter(count)
+    if count <= 0
+      0
+    elsif count == 1
+      1
+    else
+      '1+'
+    end
+  end
+
+  def custom_field_classes(field)
+    if field.verified?
+      'verified'
+    else
+      'emojify'
+    end
+  end
 end
diff --git a/app/helpers/jsonld_helper.rb b/app/helpers/jsonld_helper.rb
index 9d2b6cf00d28024db7c3cb4a5fd9a9b152fd66cf..5323972723ee324dd59f33a812235e6d7ce8c5c0 100644
--- a/app/helpers/jsonld_helper.rb
+++ b/app/helpers/jsonld_helper.rb
@@ -73,8 +73,10 @@ module JsonLdHelper
     end
   end
 
-  def body_to_json(body)
-    body.is_a?(String) ? Oj.load(body, mode: :strict) : body
+  def body_to_json(body, compare_id: nil)
+    json = body.is_a?(String) ? Oj.load(body, mode: :strict) : body
+    return if compare_id.present? && json['id'] != compare_id
+    json
   rescue Oj::ParseError
     nil
   end
diff --git a/app/helpers/mailer_helper.rb b/app/helpers/mailer_helper.rb
deleted file mode 100644
index b7e3a8da38c482db3b9ce3a2f3d0a88987b72198..0000000000000000000000000000000000000000
--- a/app/helpers/mailer_helper.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-# frozen_string_literal: true
-
-module MailerHelper
-end
diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb
index 740f7bf77135120d41c246146567ef57d0740f43..0e957e94655a4b3ef38490c75b80e8785e02fe6a 100644
--- a/app/helpers/settings_helper.rb
+++ b/app/helpers/settings_helper.rb
@@ -4,9 +4,12 @@ module SettingsHelper
   HUMAN_LOCALES = {
     en: 'English',
     ar: 'العربية',
+    ast: 'l\'asturianu',
     bg: 'Български',
     ca: 'Català',
     co: 'Corsu',
+    cs: 'Čeština',
+    cy: 'Cymraeg',
     da: 'Dansk',
     de: 'Deutsch',
     el: 'Ελληνικά',
@@ -25,19 +28,23 @@ module SettingsHelper
     io: 'Ido',
     it: 'Italiano',
     ja: '日本語',
+    ka: 'ქართული',
     ko: '한국어',
+    ml: 'മലയാളം',
     nl: 'Nederlands',
     no: 'Norsk',
     oc: 'Occitan',
     pl: 'Polszczyzna',
     pt: 'Português',
     'pt-BR': 'Português do Brasil',
+    ro: 'Limba română',
     ru: 'Русский',
-    sk: 'Slovensky',
+    sk: 'Slovenčina',
     sl: 'Slovenščina',
     sr: 'Српски',
     'sr-Latn': 'Srpski (latinica)',
     sv: 'Svenska',
+    ta: 'தமிழ்',
     te: 'తెలుగు',
     th: 'ภาษาไทย',
     tr: 'Türkçe',
diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb
index a91a2893556834024faf70c9c347c8af7612e194..033d435c49780920e2902d23ab06491bb61de2bd 100644
--- a/app/helpers/stream_entries_helper.rb
+++ b/app/helpers/stream_entries_helper.rb
@@ -12,21 +12,69 @@ module StreamEntriesHelper
     end
   end
 
+  def account_action_button(account)
+    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')])
+        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')])
+        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')])
+        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')])
+      end
+    end
+  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')
+    elsif (Setting.show_staff_badge && account.user_staff?) || all
+      content_tag(:div, class: 'roles') do
+        if all && !account.user_staff?
+          content_tag(:div, t('admin.accounts.roles.user'), class: 'account-role')
+        elsif account.user_admin?
+          content_tag(:div, t('accounts.roles.admin'), class: 'account-role admin')
+        elsif account.user_moderator?
+          content_tag(:div, t('accounts.roles.moderator'), class: 'account-role moderator')
+        end
+      end
+    end
+  end
+
+  def link_to_more(url)
+    link_to t('statuses.show_more'), url, class: 'load-more load-gap'
+  end
+
+  def nothing_here(extra_classes = '')
+    content_tag(:div, class: "nothing-here #{extra_classes}") do
+      t('accounts.nothing_here')
+    end
+  end
+
   def account_description(account)
     prepend_str = [
       [
         number_to_human(account.statuses_count, strip_insignificant_zeros: true),
-        I18n.t('accounts.posts'),
+        I18n.t('accounts.posts', count: account.statuses_count),
       ].join(' '),
 
       [
         number_to_human(account.following_count, strip_insignificant_zeros: true),
-        I18n.t('accounts.following'),
+        I18n.t('accounts.following', count: account.following_count),
       ].join(' '),
 
       [
         number_to_human(account.followers_count, strip_insignificant_zeros: true),
-        I18n.t('accounts.followers'),
+        I18n.t('accounts.followers', count: account.followers_count),
       ].join(' '),
     ].join(', ')
 
@@ -67,7 +115,7 @@ module StreamEntriesHelper
   end
 
   def acct(account)
-    if embedded_view? && account.local?
+    if account.local?
       "@#{account.acct}@#{Rails.configuration.x.local_domain}"
     else
       "@#{account.acct}"
diff --git a/app/javascript/images/icon_flag.svg b/app/javascript/images/icon_flag.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3939c9d2b3702c0630b8cc17ab6de33ef641298e
--- /dev/null
+++ b/app/javascript/images/icon_flag.svg
@@ -0,0 +1,4 @@
+<svg fill="#FFFFFF" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+  <path d="M0 0h24v24H0z" fill="none"/>
+  <path d="M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z"/>
+</svg>
diff --git a/app/javascript/images/mailer/icon_warning.png b/app/javascript/images/mailer/icon_warning.png
new file mode 100644
index 0000000000000000000000000000000000000000..7baaac61cb82648d9acc63fdbdd4a8aaa7249e8b
Binary files /dev/null and b/app/javascript/images/mailer/icon_warning.png differ
diff --git a/app/javascript/images/screen_federation.svg b/app/javascript/images/screen_federation.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7019a7356a65394cdebcb226e6ccc1667a75061d
--- /dev/null
+++ b/app/javascript/images/screen_federation.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="806.09998" width="1197.7164" viewBox="0 0 1197.7164 806.09999" id="Layer_1"><path id="path6078" d="M482.4164 557.4c-42.3-31.3-89.9-55.7-141.2-72.5-53.2-17.4-109.1-26.2-166.3-26.2-59.7 0-117.9 9.6-173.1 28.5v315.9h645.6c-21.6-95.7-80.1-182.9-165-245.7z" class="st33" fill="#fff"/><path stroke-miterlimit="10" id="path6082" d="M515.7164 589.8c-1.1 3.3-6.4 5.1-7.4 4.2l-.2-7.1.2-3.6c-86.1-74.6-203.7-120.6-333.4-120.6-61 0-119.4 10.2-173.1 28.8v313.6h641.9c-18.4-83.2-63.7-157.2-128-215.3" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6084" d="M351.5164 565.1l9.3 4.8" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6086" d="M336.5164 558c2.2 1 4.4 2 6.5 3" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6088" d="M321.5164 551.5c2.6 1 5.1 2.1 7.7 3.2" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6090" d="M304.8164 545.1c3.4 1.2 6.7 2.5 10 3.7" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><g id="g6092" transform="translate(-1343.3836 -75.800003)"><path stroke-miterlimit="10" id="path6094" d="M1890.4 836.8c1.9 3.9 3.8 7.8 5.5 11.7" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6100" d="M1880.9 818.7c1.5 2.7 2.9 5.4 4.4 8.1" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6102" d="M1871.4 802.4c1.8 2.9 3.5 5.8 5.2 8.8" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6104" d="M1860.3 785.1c2 2.9 4 5.9 5.9 8.9" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6106" d="M1848.4 768.6c2.2 2.9 4.3 5.8 6.4 8.8" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6108" d="M1834.4 751c2.6 3.1 5.2 6.3 7.7 9.5" class="st81" fill="none" stroke="#2d3f68" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></g><path id="path6110" d="M156.6164 523.5c-54.6 0-106.7 10.1-154.8 28.4V805h559.5c-59.5-164.1-218.2-281.5-404.7-281.5z" class="st82" fill="#2d3f68"/><g id="g6112" transform="translate(-1343.3836 -75.800003)"><path id="path6114" d="M2065.2 128.3c1.4 69-36.9 80.4-35.7 141.1 1.2 60.6 39.9 70.5 41.3 139.5 1.4 69-36.9 80.4-35.7 141.1 1.2 60.6 39.9 70.5 41.3 139.5 1.4 69-36.9 80.4-35.7 141.1.4 20.5 5.1 35.2 11.2 48.3H2541v-803h-487.3c6.2 13.6 11 29.7 11.5 52.4z"/></g><g id="g6116" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6118" r="33.799999" cy="645.40002" cx="2236.6001" class="st83" fill="#ebb548" stroke="#663f09" stroke-width="3.30660009" stroke-linecap="round" stroke-linejoin="round"/><g id="g6120"><path stroke-miterlimit="10" id="path6122" d="M2243.3 641.5c-2.4-5.6-8-6.2-15.8-3.2-5.7 2.2-18.2 7.3-24.5 9.9.7 8.2 4.3 15.5 9.7 21 6.7-2.6 21.3-8.2 32-12.6 14.3-5.9 12.9-9.1 10.2-14.1-2.7-5-11.6-1-11.6-1z" class="st84" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65330005"/><path stroke-miterlimit="10" id="path6124" d="M2243.4 612.3c-12.6 4.4-13.1 7.3-11.2 11.6 2.1 4.6 9.4 2.6 15.4.1 2.6-1 6.8-2.8 10.7-4.5-4.2-3.5-9.2-6.1-14.9-7.2z" class="st84" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65330005"/></g><g id="g6126"><circle id="circle6128" r="3" cy="627.70001" cx="2218.8" class="st33" fill="#fff"/></g></g><g id="g6130" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6132" r="33.799999" cy="485.79999" cx="2402.5" class="st83" fill="#ebb548" stroke="#663f09" stroke-width="3.30660009" stroke-linecap="round" stroke-linejoin="round"/><g id="g6134"><circle id="circle6136" r="3" cy="468.20001" cx="2384.8" class="st33" fill="#fff"/></g></g><path id="path6138" d="M292.3164 506.3c-2.7 0-6.7-.4-9.8-3.5-2.9-3-4.2-7.6-4-14 .1-2.2.2-4.1.2-5.9-2.9-.4-5.8-.9-8.6-1.7-17.4-4.7-31.5-16.3-39.6-32.8-1-2.1-2-4.2-2.8-6.4-.6 0-1.2 0-1.7.1-.9 2.2-1.8 4.3-2.8 6.4-8.1 16.5-22.1 28.1-39.6 32.8-2.8.8-5.7 1.3-8.6 1.7.1 1.7.1 3.7.2 5.9.3 6.4-1 11-4 14-3.1 3.2-7.1 3.5-9.8 3.5H149.6164c-13.1 0-13.1-9.7-13.1-14.9v-14.7c-2-.9-3.9-1.9-5.7-3-1.6 2.7-4.5 5.6-9.3 6.9-4.8 1.2-8.9 1.8-12.5 1.8-4.5 0-8.3-1-11.2-2.9-3.3-2.2-5.4-5.7-6-10.1-1.5-10.5-.6-17.6 2.6-21.8 1.8-2.3 4.2-3.6 7.1-3.9l5.5-.5c-9.9-1.8-15.4-7.7-16.4-17.5-.8-8.1 6.6-16.9 11-18.6 1.1-.5 2.2-.7 3.1-.7 1.8 0 3.2.8 4.2 2.2 1 1.4 1.9 4.3-2.2 8.4-.7.9-3.3 6.5-1.8 9.9.8 1.7 2.7 2.7 5.8 3.1 1.9-7.1 5.8-12.8 11.4-16.6h-.5c-3.8 0-7-1.3-9.2-3.8-2.2-2.5-3.2-6-2.7-9.9.6-4.5.6-11.5 0-21.9-.7-13.3 4.2-23.4 13-26.3 2.2-.7 4.4-1.1 6.6-1.1 3.2 0 6.4.8 9.3 2.2l.1-.1c-1.5-3.1-1.9-6.5-1.1-9.5.7-2.6 3.4-8.9 13.8-10.1 1.4-.2 3.5-.3 6.1-.3 2.1-3.3 5.4-7.6 9.2-9.8.1-.7.1-1.2.2-1.7-1.3-3-1.4-5.7-.3-8 .7-1.6 2.4-3.7 6-4.6.7-.2 1.5-.3 2.2-.3 2.9 0 5.6 1.4 7.7 4 .4-.1.7-.1 1.1-.1h.5c2.6.2 5 1.5 6.6 3.8 2.2 3 1.3 7.1-2 10.5.3 3.1 1.5 5.7 3.5 7.7.5.5 1.2 1 1.9 1.5 4.7.7 8.8 1.6 12.5 2.5 2.8.7 5.3 1.2 7.1 1.4 1.3.2 2.8.2 4.4.2 7.5 0 17.4-1.7 22.8-6.5 2.2-1.9 3.4-4.2 3.8-6.9-2.8-2.9-3.4-6.6-1.6-9.6.6-1 2.4-4 5.8-4.6.4-.1.8-.1 1.2-.1.4 0 .8 0 1.2.1 2-2 4.2-3.1 6.5-3.1.8 0 1.6.1 2.4.4 2.5.8 4.6 2.6 5.7 4.9.9 1.9 1.1 4.1.5 6.3.3 2.4.9 7.8.1 14.5 7.9.2 15.7 2.7 23.7 7.6 1.5.9 2.8 1.8 4.1 2.7.9-.3 1.9-.6 3-.8 1.6-.3 3.2-.5 4.7-.5 7 0 16.4 3.6 21.7 20.7 1.4 4.7 2.9 8.2 4 11.1 2.7 6.6 4.8 11.9-1.1 17.1-3.9 3.4-7.7 5.2-11.5 5.2-1.3 0-2.5-.2-3.7-.6v.1c16.3 3.4 27.2 14.7 31.3 32.1 3.4-.3 5.5-1.4 6.3-3.2 1.5-3.4-1-9-1.9-10-4-4-3-6.9-2.1-8.3.9-1.4 2.4-2.2 4.2-2.2 1 0 2 .2 3.1.7 4.3 1.7 11.8 10.6 11 18.6-1 9.8-6.5 15.7-16.5 17.5l5.5.6c2.8.3 5.3 1.6 7.1 3.9 3.3 4.2 4.1 11.3 2.6 21.8-.6 4.4-2.7 7.9-6 10.1-2.9 1.9-6.6 2.9-11.1 2.9-3.6 0-7.7-.6-12.5-1.8-4.8-1.2-7.7-4.2-9.3-6.9-1.9 1.1-3.8 2.1-5.7 3v14.7c0 5.2 0 14.9-13.1 14.9h-10.8c-.5.1-.8.1-1.2.1z" class="st33" fill="#fff"/><g id="g6140" transform="translate(-1343.3836 -75.800003)"><path stroke-miterlimit="10" id="path6142" d="M1527.8 400.3s4.8-3.7 2.9-6.3c-1.9-2.6-5-2.5-6.5-.9 0 0-2.4-6.1-7.2-4.9-3.7.9-4.6 3.7-2.4 7.9 0 0-8.4 42.4 35.2 53.1l4.6-29.6c-11.7.1-26.6-3.8-26.6-19.3z" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><g id="g6144"><path stroke-miterlimit="10" id="path6146" d="M1695.3 523.5c-6-.6-11.9-1.2-11.9-1.2s3.6-40.6-32.8-45.4c.6-34.6-2.4-44.8-19.1-54.9-23.7-14.4-38.7-2.2-48.8-1-1.3.2-2.9.3-4.7.3l-7.6 27.9s-9.3 39.1 7.5 73.1c16.7 34 58.5 42.4 90.7 20.9 0 0 1.2 7.2 8.4 9 7.2 1.8 22.7 4.8 24.5-7.8 1.6-12.5-.2-20.3-6.2-20.9z" class="st86" fill="#876a4d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/></g><path stroke-miterlimit="10" id="path6148" d="M1474.2 489.2c-.6-34.6 0-56.7 25.1-68.6 25.1-11.9 47.2-2.4 57.3-1.2 10.1 1.2 35.8-1.2 35.8-19.1 0 0-4.1-2.8-2.3-5.6 1.7-2.8 3.4-3.6 5.9-1.6 0 0 2.7-5.1 6.3-3.9 2.5.8 4.6 3.3 3.2 6.9 0 0 8.4 42.4-35.2 53.1 0 0 9.3 39.1-7.5 73.1-16.7 34-58.5 42.4-90.7 20.9 0 0-1.2 7.2-8.4 9-7.2 1.8-22.7 4.8-24.5-7.8-1.8-12.5 0-20.3 6-20.9 6-.6 11.9-1.2 11.9-1.2s-4.7-25.6 17.1-33.1z" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path id="path6150" d="M1510 553.9c-13 0-25.9-4-37.2-11.6l-1.5-1-.3 1.8c0 .3-1.2 6.4-7.5 8-4.4 1.1-8 1.6-11.1 1.6-7.2 0-11.1-2.7-11.9-8.4-1.6-11 0-15.7 1.6-17.7.9-1.1 2-1.7 3.4-1.8l13.2-1.3-.2-1.3c0-.2-2.4-13.5 4.5-23.2-.7 4.7.2 9.5 2.6 13.6 2.8 4.7 8.9 10.7 22.1 12.4 4.2.5 8.4.9 12.6.8 40.6-1 51.6-8.4 53.3-27l15.7 1.5c-1.7 7.8-4.1 15.1-7.4 21.7-10 19.9-29.3 31.9-51.9 31.9z" class="st4" fill="#e09c5c"/><path id="path6152" d="M1630.6 553.9c13 0 25.9-4 37.2-11.6l1.5-1 .3 1.8c0 .3 1.2 6.4 7.5 8 4.4 1.1 8 1.6 11.1 1.6 7.2 0 11.1-2.7 11.9-8.4 1.6-11 0-15.7-1.6-17.7-.9-1.1-2-1.7-3.4-1.8l-13.2-1.3.2-1.3c0-.2 2.4-13.5-4.5-23.2.7 4.7-.2 9.5-2.6 13.6-2.8 4.7-8.9 10.7-22.1 12.4-4.2.5-8.4.9-12.6.8-40.6-1-51.6-8.4-53.3-27l-15.7 1.5c1.7 7.8 4.1 15.1 7.4 21.7 10 19.9 29.3 31.9 51.9 31.9z" fill="#6e5a3d"/><path stroke-miterlimit="10" id="path6154" d="M1484 544.4v22.7c0 6.6.6 10.7 9 10.7h10.1c3.5 0 11.9 1.2 11.3-13.1-.6-14.3-.6-19.1-.6-19.1" class="st87" fill="#e09c5c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6160" d="M1460.2 515.2c-13.7.6-21-3.6-22.1-14.3-.6-6 5.4-13.1 8.4-14.3 3-1.2 3 .6.6 3s-10.7 21.5 11.9 20.3" class="st87" fill="#e09c5c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6162" d="M1581.8 460.8c-.1-.8-.4-1.7.2-2.3.6-.6 1.1-.5 2-.5 5.8.1 21.1.2 24 .4 3.6.1 3.1 2.9 1.6 6-3.9 7.6-6.4 11.5-14.2 11.4-6.5-.1-12.4-6.2-13.6-15z" fill="#33281d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6164" d="M1609.5 464.4c-3.9 7.6-6.4 11.5-14.2 11.4-1 0-2-.2-3-.5-.1-.9-.2-1.7-.2-2.6 0-5.6 2.2-10.7 5.8-14.5 4.5.1 8.6.1 9.9.2 3.7.1 3.3 2.9 1.7 6z" fill="#693131" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6166" d="M1680.4 515.2c13.7.6 21-3.6 22.1-14.3.6-6-5.4-13.1-8.4-14.3-3-1.2-3 .6-.6 3s10.7 21.5-11.9 20.3" class="st86" fill="#876a4d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6168" d="M1488.2 439.4c-5.4-8.4-13.7-10.7-20.9-8.4-7.2 2.4-10.7 11.3-10.1 22.1.6 10.7.6 17.9 0 22.7-.6 4.8 1.8 9 7.8 9s7.2-4.2 7.2-4.2 1.8 2.4 5.4 2.4c3.6 0 10.1-2.4 10.7-10.1.6-7.7.6-9 .6-9" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6170" d="M1595 506.2c-6.8 6.9-23.1 8.1-33.8 7.3-10.7-.8-8.5-7.1-8.5-16.1 0-5.5 4.3-6.5 10.8-7.3 6.5-.8 19-.4 25.2-4.8" class="st86" fill="#876a4d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6172" d="M1548.5 478.8c14.9 0 23.9-1.8 29.2-2.4 5.4-.6 13.1 1.2 13.1 9.6 0 9.6-3.6 12.5-14.3 14.3-10.7 1.8-21.5 1.8-30.4 1.2" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6174" d="M1623.7 467.4c-8.1 8.1-15.5 9-23.9 6-8.4-3-10.7-10.1-10.1-15.5.6-5.4 4.2-6 6-1.2 1.8 4.8 3 7.8 10.7 9 4.2.6 7.2-2.4 10.7-5.4 3.6-3 6-3 7.8-.6 2.1 2.8 1.2 5.3-1.2 7.7z" class="st91" fill="#fff" stroke="#7d7d65" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6176" d="M1515.1 456.1s-2.4-6-3.6-10.1c-1.2-4.2-1.8-7.2 1.8-8.4 3.6-1.2 6 1.2 7.8 5.4 1.8 4.2 3.6 10.1 3.6 10.1" class="st92" fill="none" stroke="#402f19" stroke-width="2.98460007" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6178" d="M1557 460.8c.1-.8.4-1.7-.2-2.3-.6-.6-1.1-.5-2-.5-5.8.1-21.1.2-24 .4-3.6.1-3.1 2.9-1.6 6 3.9 7.6 6.4 11.5 14.2 11.4 6.5-.1 12.5-6.2 13.6-15z" fill="#544024" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6180" d="M1632.1 440c-1.8-7.8 1.2-13.7 9.6-15.5 8.4-1.8 16.7 1.8 21.5 17.3 4.8 15.5 9.6 19.1 4.2 23.9-5.4 4.8-10.1 5.4-14.9 1.8 0 0-4.2 4.2-8.4.6s-4.2-7.8-4.2-7.8" class="st86" fill="#876a4d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6182" d="M1605.4 452c0-6.9.7-17.9 6-18.5 5.3-.6 6.9 2.8 6.4 8.8-.5 6-1 11.9-1 11.9" class="st92" fill="none" stroke="#402f19" stroke-width="2.98460007" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6184" d="M1529.3 464.4c3.9 7.6 6.4 11.5 14.2 11.4 1 0 2-.2 3-.5.1-.9.2-1.7.2-2.6 0-5.6-2.2-10.7-5.8-14.5-4.5.1-8.6.1-9.9.2-3.7.1-3.3 2.9-1.7 6z" fill="#693131" stroke="#381916" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6186" d="M1557 460.8c.1-.8.4-1.7-.2-2.3-.6-.6-1.1-.5-2-.5-5.8.1-21.1.2-24 .4-3.6.1-3.1 2.9-1.6 6 3.9 7.6 6.4 11.5 14.2 11.4 6.5-.1 12.5-6.2 13.6-15z" fill="none" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6188" d="M1504.9 467.4c8.1 8.1 15.5 9 23.9 6 8.4-3 10.7-10.1 10.1-15.5-.6-5.4-4.2-6-6-1.2-1.8 4.8-3 7.8-10.7 9-4.2.6-7.2-2.4-10.7-5.4-3.6-3-6-3-7.8-.6-2.1 2.8-1.2 5.3 1.2 7.7z" class="st91" fill="#fff" stroke="#7d7d65" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6190" d="M1490 431.3c-7.1-5.2-8.4-17 5.3-18.6 2.7-.3 8-.2 8-.2s6.4-11.5 11.7-11c5.3.5 5.5 5.2 4.3 7.5 0 0 5.9.2 4.4 6.9-.6 2.8-3.6 4.2-3.6 4.2" class="st85" fill="#fbc16c" stroke="#946f3a" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path id="path6192" d="M1499.9 459.7l-3.7 1.4c-.9.4-2-.1-2.3-1l-.1-.3c-.4-.9.1-2 1-2.3l3.7-1.4c.9-.4 2 .1 2.3 1l.1.3c.4.9-.1 1.9-1 2.3z" class="st31" fill="#e68a4c"/><path id="path6194" d="M1630.2 459.7l3.7 1.4c.9.4 2-.1 2.3-1l.1-.3c.4-.9-.1-2-1-2.3l-3.7-1.4c-.9-.4-2 .1-2.3 1l-.1.3c-.4.9.1 1.9 1 2.3z" fill="#805945"/><path stroke-miterlimit="10" id="path6196" d="M1592.7 412.4c.3-.6.7-1.3.9-2" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6198" d="M1588.8 417.1c.8-.7 1-.7 1.7-1.6" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6200" d="M1576.3 423c2.5-.6 4.9-1.4 7-2.4" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6202" d="M1560.5 424.8c1.7.1 3.5 0 5.4-.2 1.3-.1 2.6-.3 3.9-.5" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6204" d="M1533 419.3c6.5.6 11.4 2.2 16.3 3.6" class="st96" fill="none" stroke="#fbd7a3" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6206" d="M1627.4 425.2c.7.5 1.4.9 2.1 1.5" class="st97" fill="none" stroke="#b58e67" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6208" d="M1621.5 422.2c.9.4 1.9.8 2.8 1.3" class="st97" fill="none" stroke="#b58e67" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6210" d="M1607.9 419.7c2.4.1 4.8.3 7.3.7" class="st97" fill="none" stroke="#b58e67" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6212" d="M1656.5 544.4v22.7c0 6.6-.6 10.7-9 10.7h-10.1c-3.5 0-11.9 1.2-11.3-13.1.6-14.3.6-19.1.6-19.1" fill="#6e5a3d" stroke="#3b3024" stroke-width="2.38770008" stroke-linecap="round" stroke-linejoin="round"/></g><g id="g6532" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6534" r="103.3" cy="500.79999" cx="1949" fill="#4a77ab" stroke="#132137" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6536" r="74.699997" cy="500.79999" cx="1949" class="st16" fill="#51a1b5"/><g id="g6538"><path stroke-miterlimit="10" id="path6540" d="M2005.2 459.7c3.8 9.9 14.9 9.6 29.9 4.9 3.4-1.1 6.5-2.1 9.3-3.1-3.4-8.3-7.9-16-13.2-23-18.9 5.2-29.4 12.3-26 21.2z" fill="#75bd8c" stroke="#132137" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6542" d="M2017 544.7c-5.9 11 .3 18.8 10.9 22.7 7.6-9 13.7-19.4 17.9-30.6-10.8-.8-24.5-.1-28.8 7.9z" class="st140" fill="#e0b779" stroke="#132137" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6544" d="M2003.9 420.2c.4-2.2.5-4.4.5-6.5-17.8-11.3-39.3-17.3-62-15.9-19 1.2-36.5 7.5-51.2 17.5-.4 12.8 2.4 21.8 13.8 25 15.7 4.4 26.4-.3 26.4-.3s2.1 12.3 23 13.1c20.9.8 20.9-14.8 20.9-14.8s25 3.3 28.6-18.1z" class="st140" fill="#e0b779" stroke="#132137" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><path stroke-miterlimit="10" id="path6546" d="M2001.9 491.9c.4 8.1-3.7 14-13.6 17.7-9.8 3.8-20 4.2-32-6.9-12-11.1-38.3-23.9-61-20.5-28.8 4.3-36.6 23.5-36.6 23.5-1.9-2.2-5.5-6.1-12.9-9.8-.2 3.8-.1 7.6.1 11.4 3.6 56.9 52.7 100.1 109.7 96.5 6.3-.4 12.4-1.4 18.3-2.8-2.6-39.5-19.3-67.9-19.3-67.9 13.7 5.7 27.8 5.7 45.9-2.8 18.1-8.5 23.6-24.6 20.4-38-3.3-13.4-19.3-8.5-19-.4z" fill="#75bd8c" stroke="#1c3b28" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" id="circle6548" r="9" cy="510.89999" cx="1898.9" class="st142" fill="#51a1b5" stroke="#1c3b28" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6550" r="9" cy="479.5" cx="1970.5" fill="#4a77ab"/><path stroke-miterlimit="10" id="path6552" d="M1879.4 530.7c-2.2 4.6 0 11.8 10.8 14.3s24.7-.1 30.8-6.5c6.5-6.9 8.8-13.5 3.5-17.3-5.3-3.8-11.3.4-14.3 4.7s-10.1 4.7-17.7 1.8c-7.5-2.9-10.5-2.6-13.1 3z" class="st142" fill="#51a1b5" stroke="#1c3b28" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6554" d="M1956.1 381.4c8.2-3 11.7-4.5 14.4-5.7 2.7-1.2 5-.4 6.4 2.4 1.3 2.8-.8 5.7-6 7.7-5.3 2-13 5-13 5" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6556" d="M1950.6 411.4c.1 5.7-1.9 11.2 4.1 11.3 5.9.1 6.2-3.1 6.2-5.9 0-2.8-.1-4.7-.1-4.7" class="st26" fill="#e09c5c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6558" d="M1913.2 410.2c4.9 3.8 12.6 2.5 14.2.1 1.6-2.4-.4-3.4-2.3-2.3s-7.2 1.6-9.7.2c-2.5-1.3-3.8.8-2.2 2z" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6560" d="M1921.1 396c0 10.2 2.3 18.5 12 19s17.9-.1 23.8-.9c5.9-.8 11.1-3.5 10.9-13.7-.1-10.2-.1-25.2-.1-25.2s8.4 3 15.6-.8c7.7-4 9.7-6.7 11-8.8 1.1-1.9-1.2-7.9-6.1-4.1-4.9 3.8-10.1 6.1-15.2 3.9-5.1-2.2-7.2-5-9.9-9.3-2.5-3.9-7.7-8.1-20.6-7.7-14 .5-21.9 13-21.6 25.1.3 12.1.2 22.5.2 22.5z" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path id="path6562" d="M1939.7 414.1c-2.2 0-4.4-.1-6.6-.1-7.6-.3-11-5.9-11-18v-5.8c6.6-.2 11.3 3.5 11.6 8 .5 7.5 6.8 10 15.7 10h5.2c4 0 8.7 0 11.6-2.2-1.6 5.2-5.7 6.5-9.4 7-3.8.6-9.8 1.1-17.1 1.1z" class="st4" fill="#e09c5c"/><path stroke-miterlimit="10" id="path6564" d="M1929.4 357.9c-2.1-7-10.8-9.6-15.6-3.8-4.8 5.8-9.9 17.9-6.3 21.1 3.6 3.2 5.2 2.3 7.1 1.5 0 0 2.3 4.1 6.9.9 4.5-3.2 6-9.6 6-9.6" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6566" d="M1938 378c5.7 4.2 11.2 4.4 14.7 1.8 3.4-2.5 5.6-5.2 4-6.9-1.6-1.7-3.5-.1-5.5 1.3-2 1.4-5.1 1.8-7.9.1-2.8-1.7-5-2.2-6.3-.8-1.4 1.5-.5 3.4 1 4.5z" fill="#fbe6c6" stroke="#668794" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path id="path6568" d="M1940.7 364.8c0 3.8-.2 4.2-1.2 4.2s-1.3-.5-1.3-4.2c0-4.6.3-5.1 1.3-5.1s1.2.6 1.2 5.1z"/><path stroke-miterlimit="10" id="path6570" d="M1926 380.7c-8.2-3-8.1-3-10.7-4.2-2.6-1.2-5-.4-6.4 2.4-1.3 2.8.8 5.7 6 7.7 5.3 2 9.4 3.5 9.4 3.5" class="st25" fill="#fbc16c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6572" d="M1928.4 412.5c.1 5.7-1.9 11.2 4.1 11.3 5.9.1 6.2-3.1 6.2-5.9 0-2.8-.1-4.7-.1-4.7" class="st26" fill="#e09c5c" stroke="#946f3a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><g id="g6574"><path stroke-miterlimit="10" id="path6576" d="M1930.3 478.8l-54.2 14.5c-6.4 1.7-13-2.1-14.7-8.5l-.3-1c-1.7-6.4 2.1-13 8.5-14.7l54.2-14.5c6.4-1.7 13 2.1 14.7 8.5l.3 1c1.7 6.4-2.2 13-8.5 14.7z" class="st10" fill="#fff" stroke="#7d7d65" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6578" d="M2002.5 559.5l-32.9 8.8c-5.6 1.5-11.4-1.9-12.9-7.4-1.5-5.6 1.9-11.4 7.4-12.9l32.9-8.8c5.6-1.5 11.4 1.9 12.9 7.4 1.6 5.6-1.8 11.4-7.4 12.9z" class="st10" fill="#fff" stroke="#7d7d65" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6580" d="M2037.3 515.3l-10.8 2.9c-5.6 1.5-11.4-1.9-12.9-7.4-1.5-5.6 1.9-11.4 7.4-12.9l10.8-2.9c5.6-1.5 11.4 1.9 12.9 7.4 1.5 5.6-1.8 11.4-7.4 12.9z" class="st10" fill="#fff" stroke="#7d7d65" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><path id="path6582" d="M1933.9 372.1l-2.9-.1c-1 0-1.8-.9-1.8-1.9v-.4c0-1 .9-1.8 1.9-1.8l2.9.1c1 0 1.8.9 1.8 1.9v.4c0 1.1-.9 1.9-1.9 1.8z" class="st31" fill="#e68a4c"/><path stroke-miterlimit="10" id="path6584" d="M1986.7 443.9c7.1-1.4 15.8-4.7 20.3-12" class="st36" fill="none" stroke="#51a1b5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6586" d="M1883.3 432.1c3.7 9.5 9.5 14.2 22.5 16" class="st36" fill="none" stroke="#51a1b5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6588" r="2.0999999" cy="424.70001" cx="2009.9" class="st16" fill="#51a1b5"/><path stroke-miterlimit="10" id="path6590" d="M1949 587.1c-27.7 0-52.4-13.1-68.2-33.4" fill="none" stroke="#66a77c" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/><g id="g6592"><path d="M1934.9 271.4v30.3h-13.5l22.6 27.6 22.6-27.6h-13.4v-30.3z" stroke-miterlimit="10" id="polygon6594" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M1939.7 275.79999v10.5" stroke-miterlimit="10" id="line6596" class="st76" fill="none" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M1939.7 293.39999V301.5" stroke-miterlimit="10" id="line6598" class="st76" fill="none" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g></g><g id="g6600" transform="translate(-1343.3836 -75.800003)"><g id="g6602"><path id="path6604" d="M1784.9 522.9c0-.6-.4-1-1-1h-29.3v-16.3h29.3c.6 0 1-.4 1-1v-11.4l25.1 20.5-25.1 20.5v-11.3z" class="st143" fill="#f1614e"/><path id="path6606" d="M1785.9 495.4l22.5 18.4-22.5 18.4v-9.3c0-1.1-.9-2-2-2h-28.3v-14.3h28.3c1.1 0 2-.9 2-2v-9.2m-2-4.3v13.5h-30.3v18.3h30.3v13.5l27.6-22.6-27.6-22.7z" class="st144" fill="#9c3b2d"/></g><path d="M1757.9 509.10001h10.6" stroke-miterlimit="10" id="line6608" class="st79" fill="#f47c53" stroke="#fdbc61" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M1775.6 509.10001h8" stroke-miterlimit="10" id="line6610" class="st79" fill="#f47c53" stroke="#fdbc61" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><g id="g6612" transform="translate(-1343.3836 -75.800003)"><g id="g6614"><path id="path6616" d="M2084.4 419.8l23.3-17.7c.2-.2.3-.4.4-.7 0-.3 0-.5-.2-.7l-6.9-9 32.4 1.1-7.5 31.5-6.9-9c-.2-.3-.5-.4-.8-.4-.2 0-.4.1-.6.2l-23.3 17.7-9.9-13z" class="st143" fill="#f1614e"/><path id="path6618" d="M2103.1 392.7l29 1-6.7 28.3-5.6-7.4c-.3-.4-.8-.7-1.3-.8h-.3c-.4 0-.9.1-1.2.4l-22.5 17.1-8.7-11.4 22.5-17.1c.9-.7 1-1.9.4-2.8l-5.6-7.3m-4.2-2.1l8.2 10.7-24.1 18.3 11.1 14.6 24.1-18.3 8.2 10.7 8.3-34.7-35.8-1.3z" class="st144" fill="#9c3b2d"/></g><path d="M2089.1001 420.5l8.3999-6.29999" stroke-miterlimit="10" id="line6620" class="st79" fill="#f47c53" stroke="#fdbc61" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M2103.2 409.89999L2109.6001 405" stroke-miterlimit="10" id="line6622" class="st79" fill="#f47c53" stroke="#fdbc61" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><path stroke-miterlimit="10" id="path6624" d="M47.9164 462.8c13.3-4.1 19.9.8 23.6 7.7 8.2 15.4-1.9 21.1-28.8 31.2-27 10.1-40.4 15.2-40.4 15.2l-1.3-56.9c14.7-5.1 25.3 2.9 27 8.8-.1.1 9.5-3.9 19.9-6" fill="#587faa" stroke="#000" stroke-width="2"/><path id="path6626" d="M2.4164 474.9c2.1-.4 3.9-.6 5.4-.6 4.6 0 8.1 1.5 10 8.6l.5 2 2-.6c.1 0 10.4-3.4 22.4-7.4 2.5-.8 4.9-1.3 7.1-1.3 7.7 0 12.2 5.3 13.3 15.9-5.1 3.1-12.6 6.1-22 9.6l-37.8 14.2-.9-40.4z" class="st82" fill="#2d3f68"/><path stroke-miterlimit="10" id="path6628" d="M6.0164 564.9l12.2 25.7s7.2 5.9 11.4-3.8l-15.6-27-8 5.1z" class="st146" fill="#191b22" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><g id="g6630" transform="translate(-1343.3836 -75.800003)"><path id="path6632" d="M1346.3 567.9c6.1-2.8 11.8-4.2 16.9-4.2 11.8 0 19.1 7.9 19.3 21.1 0 .3.2.6.4.8.2.1.4.2.6.2h.3s2-.6 4.8-.6c5.8 0 13.5 2.3 17 13.4 5.1 15.9-14.6 25.5-29 32.5l-.8.4c-14.1 6.9-20.2 9.4-28.7 13l-.7.3-.1-76.9z" class="st147" fill="#587faa"/><path id="path6634" d="M1363.2 562.6v2c11.4 0 18.1 7.3 18.3 20.1 0 .6.3 1.2.8 1.6.3.3.8.4 1.2.4.2 0 .4 0 .6-.1 0 0 1.9-.5 4.6-.5 5.5 0 12.7 2.2 16.1 12.7 4.9 15.1-14.4 24.4-28.5 31.3l-.8.4c-13.7 6.7-19.8 9.3-27.9 12.7l-.3-74.7c5.7-2.6 11.1-3.9 15.9-3.9v-2m0 0c-5.3 0-11.3 1.5-17.9 4.6l.3 78.9c9.6-4.1 15.5-6.5 30.7-13.9 14.6-7.1 35.8-17.1 30.3-34.1-3.9-12-12.5-14.1-18-14.1-3 0-5.1.6-5.1.6-.3-14-8.2-22-20.3-22z"/></g><path id="path6636" d="M3.9164 509.1c1.1-.1 2.2-.2 3.2-.2 12.9 0 16.5 10.9 17.2 20l.3 3.3 2.8-1.8c.1 0 6.3-4 12.9-4 7.3 0 12.3 4.8 14.9 14.4-6.1 5.5-15.1 9.9-22.4 13.5l-.7.4c-13.7 6.7-19.8 9.3-27.9 12.7l-.3-58.3z" class="st82" fill="#2d3f68"/><g id="g6638" transform="translate(-1343.3836 -75.800003)"><path id="path6640" d="M1346.2 707.5c7-2.8 13.8-4.3 19.8-4.3 13.2 0 21.1 7 21.6 19.3.4 8-9.2 14.2-9.3 14.2-.5.3-.6.9-.3 1.3.2.3.5.5.9.5.2 0 .3 0 .5-.1s16.6-8.5 28.6-14.3c4-1.9 8.2-2.9 12.1-2.9 7.4 0 13.4 3.4 16.5 9.2 4.6 8.8-2.8 14.9-3.1 15.2-.4.3-.5.8-.2 1.3.2.3.5.5.9.5.1 0 .2 0 .3-.1 0 0 3.3-1.2 7.6-1.2 5.6 0 13.3 2 18.1 11.7 8.5 16.9-4.7 24.5-12.6 29-9 5.2-38.1 23.4-39.8 24.4l-61.1 24.7-.5-128.4z" class="st147" fill="#587faa"/><path id="path6642" d="M1366 702.1v2c6 0 11.1 1.6 14.6 4.5 3.8 3.1 5.8 7.8 6.1 13.9.3 7.4-8.8 13.3-8.9 13.4-.9.6-1.2 1.8-.7 2.7.4.6 1 1 1.7 1 .3 0 .6-.1.9-.2.2-.1 16.5-8.5 28.6-14.3 3.8-1.9 7.9-2.8 11.7-2.8 7 0 12.7 3.2 15.6 8.7 4.2 8.1-2.6 13.7-2.8 13.9-.8.6-1 1.7-.5 2.5.4.6 1 1 1.7 1 .2 0 .5 0 .7-.1 0 0 3.1-1.1 7.3-1.1 7.7 0 13.5 3.7 17.2 11.1 7.4 14.8-2.4 22.1-12.2 27.7-8.9 5.1-37.4 22.9-39.7 24.4l-59.7 24.1-.4-126.3c6.6-2.6 13.1-4 18.8-4v-2.1m0 0c-6.3 0-13.5 1.6-20.9 4.7l.4 130.6 62.6-25.3s30.5-19.1 39.8-24.5c7.7-4.4 21.8-12.6 13-30.3-5-10-13-12.2-19-12.2-4.6 0-7.9 1.3-7.9 1.3s8.4-6.7 3.4-16.4c-3.3-6.3-9.8-9.8-17.3-9.8-4 0-8.3 1-12.6 3-12.2 5.9-28.6 14.3-28.6 14.3s10.2-6.5 9.8-15.1c-.6-13.8-9.9-20.3-22.7-20.3z"/></g><path id="path6644" d="M3.8164 646.2c1.5-.3 2.9-.4 4.2-.4 4.5 0 8.1 1.5 10.4 4.2 2.5 2.9 3.5 7.2 2.8 12.2l-.3 2 2 .3s3 .5 4.7 3.1c1.3 2 1.6 4.9.7 8.4l-1 4 3.7-1.6c.2-.1 16.1-7.1 25.7-11.7 2.3-1.1 5.1-2.7 7.5-3.5 4.9-1.7 10.7 1.2 12.5 3.6 2 2.7 5.8 11.9 1.2 16.6l-12.5 9.8 9.3-3.9c.1-.1 13.1-7.5 22.9-7.5 2.3 0 4.1.4 5.4 1.3 6.6 4.1 11.3 10.7 12.7 17.7-3.2 4.5-8.5 7.6-12.1 9.7-8.9 5.1-37.4 22.9-39.7 24.4l-59.7 24.1-.4-112.8z" class="st82" fill="#2d3f68"/><path d="M30.1164 786l13.1 18.6h-24.5z" stroke-miterlimit="10" id="polygon6646" class="st146" fill="#191b22" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><g id="g6648" transform="translate(-1343.3836 -75.800003)"><path id="path6650" d="M1346.3 879.4l-.5-70.5c11.7-7 21.4-10.6 28.7-10.6 7.6 0 12.3 3.9 14 11.5.1.3.3.6.6.7.1 0 .2.1.4.1s.4-.1.6-.2c.1-.1 12.8-9.1 25.8-9.1 7.3 0 13.3 2.9 17.9 8.5 5.5 6.8 7.7 13.4 6.5 19.4-1.9 9.1-10.8 15.5-18 19.3-4.2 2.2-11.1 5.7-19 9.7-14.6 7.4-32.7 16.7-40.6 21.1h-16.4z" class="st147" fill="#587faa"/><path id="path6652" d="M1374.4 799.3c7.1 0 11.5 3.6 13 10.7.1.7.6 1.2 1.2 1.4.2.1.5.1.7.1.4 0 .8-.1 1.2-.4.1-.1 12.5-8.9 25.2-8.9 7 0 12.8 2.7 17.2 8.1 5.3 6.6 7.4 12.8 6.3 18.6-1.9 9.2-11.8 15.6-17.5 18.6-4.2 2.2-11 5.7-18.9 9.7-14.5 7.4-32.4 16.5-40.5 21h-15l-.5-68.9c11.3-6.6 20.6-10 27.6-10m0-2c-7.1 0-16.8 3.3-29.7 11l.5 72h17.5c11.8-6.7 47.4-24.5 59.8-31 12.4-6.5 28.3-20 11.9-40.2-5.4-6.6-12.1-8.9-18.7-8.9-13.5 0-26.4 9.3-26.4 9.3-1.5-7.3-6.2-12.2-14.9-12.2z"/></g><path id="path6654" d="M3.8164 802.6l-.4-55.6c8.8-4 15.1-5.8 19.6-5.8 4.5 0 9.8 1.5 10.9 13.2l.3 2.7 2.5-1c.8-.3 20.3-8.4 28-12.3 1.7-.9 4.9-1.8 8.5-1.8 6.1 0 16.4 2.6 18.2 20-3.8 4.6-9.2 7.9-13.1 10-4.2 2.2-11.1 5.7-19 9.7-14.5 7.4-32.4 16.5-40.5 21h-15z" class="st82" fill="#2d3f68"/><path stroke-miterlimit="10" id="path6656" d="M262.5164 805c120.1-133.6 245.9-175.3 283.3-185.2-11.4-12.4-24.7-17.1-37.5-28.3l-.2-7.2c-142.4 45.1-254 137.7-326 219 0 0-.2.6-.7 1.7h81.1z" class="st146" fill="#191b22" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><g id="g6658" transform="translate(-1343.3836 -75.800003)"><path id="path6660" d="M1537.3 879.8c40.6-45 85.7-85.2 134.2-119.5 59.5-42.1 122.3-73.7 186.7-94.1 10.1 9.2 19.9 18.9 29.1 28.8-38.1 10.4-163.2 52.8-281.9 184.8h-68.1z" class="st82" fill="#2d3f68"/><path id="path6662" d="M1858 667.3c9.6 8.7 18.8 17.8 27.5 27.2-20.7 5.7-59.7 18.8-107.9 45.5-63.1 35-121.2 81.7-172.6 138.8h-65.4c40.1-44.3 84.7-83.9 132.5-117.7 59.3-41.9 121.8-73.4 185.9-93.8m.1-2.1c-140.4 44.4-250.9 135.2-323 215.6h70.8c120.1-133.6 245.9-175.3 283.3-185.2-9.7-10.6-19.9-20.7-30.6-30.4h-.5z"/></g><circle stroke-miterlimit="10" id="circle6664" r="56.5" cy="215.40001" cx="893.21649" class="st1" fill="none" stroke="#95b893" stroke-width="2"/><g id="g6666" transform="translate(-1343.3836 -75.800003)"><path id="path6668" d="M2236.6 202.6c48.8 0 88.6 39.7 88.6 88.6 0 48.9-39.7 88.6-88.6 88.6-48.9 0-88.6-39.8-88.6-88.6s39.7-88.6 88.6-88.6m0-3.3c-50.7 0-91.8 41.1-91.8 91.8 0 50.7 41.1 91.8 91.8 91.8 50.7 0 91.8-41.1 91.8-91.8 0-50.7-41.1-91.8-91.8-91.8z" class="st148" fill="#95b893"/></g><circle stroke-miterlimit="10" id="circle6670" r="46.299999" cy="410" cx="1059.1165" class="st149" fill="none" stroke="#95b893" stroke-width="3.25040007"/><g id="g6672" transform="translate(-1343.3836 -75.800003)"><path id="path6674" d="M2402.5 414.1c39.5 0 71.7 32.2 71.7 71.7s-32.2 71.7-71.7 71.7-71.7-32.2-71.7-71.7 32.1-71.7 71.7-71.7m0-3.3c-41.4 0-75 33.6-75 75s33.6 75 75 75 75-33.6 75-75-33.6-75-75-75z" class="st148" fill="#95b893"/></g><circle stroke-miterlimit="10" id="circle6676" r="51.099998" cy="569.60004" cx="893.21649" class="st149" fill="none" stroke="#95b893" stroke-width="3.25040007"/><circle stroke-miterlimit="10" id="circle6678" r="94.699997" cy="569.60004" cx="893.21649" class="st149" fill="none" stroke="#95b893" stroke-width="3.25040007"/><circle stroke-miterlimit="10" id="circle6680" r="76.099998" cy="569.60004" cx="893.21649" class="st149" fill="none" stroke="#95b893" stroke-width="3.25040007"/><circle stroke-miterlimit="10" id="circle6688" r="11.7" cy="523.5" cx="810.21649" fill="#51a1b5" stroke="#31446e" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" id="circle6690" r="11.7" cy="405.90002" cx="985.0163" fill="#a7658d" stroke="#4b2254" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" id="circle6692" r="8.1000004" cy="445.29999" cx="1090.6165" fill="#a8c875" stroke="#4b2254" stroke-width="2.75029993" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" id="circle6694" r="11.7" cy="617.10004" cx="951.71649" class="st29" fill="#fbe6c6" stroke="#668794" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6696" r="7" cy="617.40002" cx="956.31635" class="st30" fill="#668794"/><circle stroke-miterlimit="10" id="circle6698" r="19.9" cy="280.80002" cx="829.71649" class="st29" fill="#fbe6c6" stroke="#668794" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6700" r="11.9" cy="286.10001" cx="823.91644" class="st30" fill="#668794"/><circle stroke-miterlimit="10" id="circle6702" r="14.2" cy="499.70001" cx="958.61639" fill="#a34c4c" stroke="#381916" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6704" r="2.5999999" cy="500.40002" cx="951.61639" class="st39" fill="#381916"/><circle id="circle6706" r="2.5999999" cy="492.29999" cx="954.61639" class="st39" fill="#381916"/><circle id="circle6708" r="2.5999999" cy="493.60004" cx="962.5163" class="st39" fill="#381916"/><ellipse stroke-miterlimit="10" id="ellipse6710" ry="8.2004271" rx="6.6003442" cy="1128.4603" cx="-116.2824" class="st84" transform="rotate(-73.770504)" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65338624"/><ellipse stroke-miterlimit="10" id="ellipse6712" ry="4.4000001" rx="5.4000001" cy="1138.6377" cx="198.54999" class="st84" transform="rotate(-58.7950001)" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65330005"/><ellipse stroke-miterlimit="10" id="ellipse6714" ry="4.8000002" rx="4.4000001" cy="717.47546" cx="892.77887" class="st84" transform="rotate(-18.4680007)" fill="#ad6a3b" stroke="#663f09" stroke-width="1.65330005"/><circle stroke-miterlimit="10" id="circle6716" r="14.2" cy="234.09999" cx="949.71649" fill="#ce8c59" stroke="#381916" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle id="circle6718" r="2.5999999" cy="234.7" cx="942.71649" class="st39" fill="#381916"/><circle id="circle6720" r="2.5999999" cy="226.7" cx="945.71649" class="st39" fill="#381916"/><circle id="circle6722" r="2.5999999" cy="227.99998" cx="953.71649" class="st39" fill="#381916"/><g id="g6724" transform="translate(-1343.3836 -75.800003)"><path stroke-miterlimit="10" id="path6726" d="M1606.2 856.8c19-20 38.1-34.7 38.1-34.7" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6728" d="M1621.3 816.8c21-19.5 42.5-34.2 42.5-34.2" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6730" d="M1675.5 791.4c22.5-19 42-30.8 42-30.8" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6732" d="M1717 743.5c22-15.1 42-23.9 42-23.9" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6734" d="M1768.8 733.2c23.4-14.7 51.3-25.9 51.3-25.9" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6736" d="M1792.7 703.9c23.9-11.7 48.4-20.5 48.4-20.5" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6738" d="M1844 697.6c14.7-6.8 25.4-9.8 25.4-9.8" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" id="path6740" d="M1554.4 879.3c21-23 42-41 42-41" class="st153" fill="#ce8c59" stroke="#587faa" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></g><g id="g6742" transform="translate(-1343.3836 -75.800003)"><g id="g6744"><path d="M2402.5 485.79999l-1.5 1.40002" stroke-miterlimit="10" id="line6746" class="st1" fill="none" stroke="#95b893" stroke-width="2"/><path d="M2398.2 489.89999L2309.7 575" stroke-miterlimit="10" id="line6748" fill="none" stroke="#95b893" stroke-width="2" stroke-dasharray="3.9,3.9"/><path d="M2308.3 576.40002l-1.5 1.39997" stroke-miterlimit="10" id="line6750" class="st1" fill="none" stroke="#95b893" stroke-width="2"/></g></g><g id="g6752" transform="translate(-1343.3836 -75.800003)"><g id="g6754"><path d="M2236.6001 550.70001v-2" stroke-miterlimit="10" id="line6756" class="st1" fill="none" stroke="#95b893" stroke-width="2"/><path d="M2236.6001 544.59998V295.20001" stroke-miterlimit="10" id="line6758" fill="none" stroke="#95b893" stroke-width="2" stroke-dasharray="4.0554,4.0554"/><path d="M2236.6 293.2v-2l1.3 1.5" stroke-miterlimit="10" id="polyline6760" class="st1" fill="none" stroke="#95b893" stroke-width="2"/><path d="M2240.3999 295.70001l111.5 130.79999" stroke-miterlimit="10" id="line6762" fill="none" stroke="#95b893" stroke-width="2" stroke-dasharray="3.9514,3.9514"/><path d="M2353.2 428l1.3 1.5" stroke-miterlimit="10" id="line6764" class="st1" fill="none" stroke="#95b893" stroke-width="2"/></g></g><g id="g6766" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6768" r="33.799999" cy="291.20001" cx="2236.6001" class="st83" fill="#ebb548" stroke="#663f09" stroke-width="3.30660009" stroke-linecap="round" stroke-linejoin="round"/><g id="g6770"><circle id="circle6772" r="3" cy="273.60001" cx="2218.8" class="st33" fill="#fff"/></g></g><g id="g6774" transform="translate(-1343.3836 -75.800003)"><circle stroke-miterlimit="10" id="circle6776" r="33.799999" cy="291.20001" cx="2236.6001" class="st83" fill="#ebb548" stroke="#663f09" stroke-width="3.30660009" stroke-linecap="round" stroke-linejoin="round"/><g id="g6778"><circle id="circle6780" r="3" cy="273.60001" cx="2218.8" class="st33" fill="#fff"/></g></g><circle id="circle6906" r="3.9000001" cy="445.29999" cx="1090.6165" fill="#b4dcf5"/></svg>
diff --git a/app/javascript/images/screen_hello.svg b/app/javascript/images/screen_hello.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7bcdd0afd573f6984b90bf8f39def7041b478013
--- /dev/null
+++ b/app/javascript/images/screen_hello.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="803.09998" width="1197.8285" viewBox="0 0 1197.8284 803.09996" id="Layer_1"><path id="path6218" d="M419.21425 718.72051s1 40 2 51 3 16 20 17 41-2 50-4 16-6 14-29-4-51-4-51" class="st6" fill="#e09c5c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6220" d="M504.21425 771.52051l-.1-.6c-1.5-5.7-4.5-7-8-6.3-4.8 1-6.1 7.7-6.9 16.7 0 .4-.1.8-.1 1.3l.7.3c.4-.1.9-.2 1.3-.3 5.9-1.2 10.9-3.4 13.1-11.1z" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6222" d="M510.81425 399.72051c46-5 79-28 84-32 0 0-14-12-3-20s18 2 18 2 23.5-29.9 43.5-13.9c20 16 27.5 32.9 20.5 48.9s-52 72-147 85" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6224" d="M239.81425 697.72051c-16 15-41 23-54 5s-4-26-7-30-21 8-13 31 54 48 97 14" class="st4" fill="#e09c5c"/><path id="path6226" d="M500.21425 361.82051s34.6 70.9 43.1 175.4c7.2 89 15 139-46 168s-142 24-180 25-78-4-88-47 .5-76.5.5-76.5 1.4-71.2-2.1-82.7-9.2-28.7-9.2-28.7-5.7 40.1-35.5 53.6c-29.8 13.6-56.1.8-53.9-36.5 0 0-25.5-42.6-37.600004-79.9-12.1-37.3 19.800004-73.9 78.300004-58.8 2-71 63.6-130.7 149.1-137.7 85.4-7.1 106.3 38.7 151.9 40.7 44 2 75-12 98-35s70-53 107-29c0 0 18-6 20 10s-7 16-12 19c0 0 7 22-7 25s-12-18-12-18-23-3-42 27-47.2 70.2-122.6 86.1c-16.1 1.4-29.5-3.9-29.5-3.9" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6228" d="M259.81425 704.72051c0 23-4 53-5 64s3 22.4 21 23c28 1 82 5 87-12 6.3-21.6 5-58 0-70" class="st6" fill="#e09c5c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6230" d="M295.01425 792.42051c.8-9.7 1.8-15.7 6.8-16.7s8.8 3.1 8.9 17.1" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6232" d="M311.01425 792.42051c.8-9.7 1.8-15.7 6.8-16.7s8.8 3.1 8.9 17.1" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6234" d="M326.81425 792.72051c.8-9.7 2-17 7-18s8.9 2.1 9 16" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6236" d="M332.61425 746.52051h-15.4c-7.8 0-14.2-6.4-14.2-14.2 0-7.8 6.4-14.2 14.2-14.2h15.4c7.8 0 14.2 6.4 14.2 14.2 0 7.8-6.4 14.2-14.2 14.2z" fill="#fbc16c"/><path id="path6238" d="M127.01425 433.92051c7.3 9.1 20.6 38.2 19.8 61-.9 22.9 23.8 32.8 36.8 13 13-19.8 16.6-58.4 7.6-77.2-9-18.9-13.9-26-13.9-26s-4.9 9-17.5 10.8c-12.6 1.8-13-3.1-17.3-9.8 0 0 .6 7.4-10.6 11.5-11.2 4.2-14.8-5-14.8-5s2.7 12.7 9.9 21.7z" class="st4" fill="#e09c5c"/><path id="path6240" d="M309.31425 728.32051c-21.3 0-36.8-2.7-48.9-8.4-15.4-7.3-25-19.4-29.1-37.2-9.8-42 .4-75.1.5-75.4l.1-.3v-.3s.1-3.7.1-9.7c13.9.5 33.3 2.8 50.3 10.8 16.8 7.9 27.4 19.6 31.6 34.6 9.3 33.4 33.5 49.6 74.1 49.6 12.6 0 27-1.5 43.9-4.6 8.6-1.6 17.1-2.8 25.3-4 38.7-5.6 72.8-10.5 87.9-47.9-3.3 28.9-14.8 51.7-48.6 67.8-51.3 24.4-116.2 24.5-159.1 24.6-7.7 0-14.3 0-20.1.2-2.9.1-5.5.2-8 .2z" class="st4" fill="#e09c5c"/><path id="path6242" d="M417.81425 390.12051c1.3-8.5 2-14.7-7.8-12.6-9.8 2.1-69.8 18-80.5 20.3-10.8 2.3-8.7 12.1 1.8 18s39.7 23.2 51.7 21.6c12-1.6 22.7-3.8 27.6-19.2 4.9-15.3 7.2-28.1 7.2-28.1z" fill="#2e2314" stroke="#2b2011" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><g transform="translate(-77.185754 15.820514)" id="g6244"><path id="path6246" d="M458.6 419.7c-11.4 0-36.3-14.2-46.9-20.2l-2.2-1.3c-5.1-2.9-8.4-7.1-7.9-10.2.3-2 2.3-3.4 5.5-4.1 5.5-1.2 24-5.9 41.8-10.5l3.8-1c15.9 4.2 28.4 14.9 33.4 28.7l-.2.7c-4.5 14-13.6 16.2-25.9 17.8-.5.1-.9.1-1.4.1z" fill="#ad4949"/></g><g transform="translate(-77.185754 15.820514)" id="g6248"><path id="path6250" d="M404 397c-3.6-2.6-5.6-6.3-5-9.5.5-2.8 2.7-4.7 6.3-5.4 5.8-1.2 25.1-6.2 43.7-11 8.9-2.3 17.5-4.5 24.3-6.2l3.4 15L404 397z" class="st33" fill="#fff"/><path id="path6252" d="M471.9 367.4l2.5 11.1-70 16.4c-2.5-2.1-3.9-4.7-3.5-6.9.5-2.6 3.2-3.5 4.8-3.9 5.8-1.2 25.1-6.2 43.8-11 8.2-2.1 16-4.1 22.4-5.7m3-4.9c-20.4 5.1-61.2 15.8-70 17.7-10.3 2.2-10.6 13-1.3 19l75.6-17.8-4.3-18.9z" class="st42" fill="#7d7d65"/></g><path id="path6254" d="M215.61425 319.92051c-20.7 3.4-36.9-.3-43.7-27.4-6.8-27.1 17-58.9 51.2-71.3 34.2-12.4 68-2.3 68-2.3s9.5-22.5 12.8-35.5c3.3-13 13.3-14.1 23.6 5.2 0 0 28.8-4.1 32.3 26.8 3.6 30.9-20.7 46.4-20.7 46.4" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6256" d="M327.61425 188.52051c4.3 10.3 2.9 22.9 2.7 27" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><g transform="translate(-77.185754 15.820514)" id="g6258"><path id="path6260" d="M358.6 376.9c2.2 5.7 6.2 9.9 8.9 8.3 2.7-1.6 2.9-5.7.4-12.4-2.4-6.6-13.6-29.8-16.6-34.3-3-4.5-6.4-5.8-9.1-4.2-2.7 1.6-1.9 5.5-.1 9.2 1.9 3.8 16.5 33.4 16.5 33.4z"/></g><g transform="translate(-77.185754 15.820514)" id="g6262"><path id="path6264" d="M387.3 470.6c-4.3 0-8.8-.5-13.2-1.6-21.2-5.2-32.9-21.5-36.5-34-2.3-8-1.6-14.9 2-18.5 3.2-3.3 6.7-5 10.2-5 7.5 0 14.4 7.2 17.8 11.5 7.6 9.5 14.8 14.3 21.4 14.3 5.3 0 9.9-3 13.7-9 10-15.4 12.7-34.1 8.2-55.4-1.5-7.1.3-11.2 2.1-13.4 1.8-2.3 4.5-3.6 7.3-3.6 1.6 0 3 .4 4.2 1.2 18.2 11.8 20.2 52 13.6 74.4-5.6 18.8-23.9 39.1-50.8 39.1z" class="st33" fill="#fff"/><path id="path6266" d="M420.2 357.9c1.2 0 2.2.3 3.1.9 7.6 4.9 13 16 15.2 31.2 2 13.6 1 29.3-2.5 41-2.9 9.9-9.1 19.2-17.3 26-9.1 7.6-20 11.6-31.5 11.6-4.2 0-8.4-.5-12.7-1.6-20.4-5-31.6-20.7-35-32.6-2.1-7.2-1.5-13.5 1.5-16.5 2.9-2.9 5.8-4.4 8.8-4.4 6.9 0 13.7 7.5 16.3 10.7 8 10 15.7 15 22.9 15 6 0 11.2-3.3 15.4-9.9 10.3-15.9 13.1-35 8.4-56.9-1.1-4.9-.5-9.1 1.7-11.7 1.5-1.8 3.6-2.8 5.7-2.8m0-4c-6.7 0-14.1 6.4-11.3 19.4 3.6 16.6 3.6 36-7.9 53.8-3.8 5.9-8 8.1-12.1 8.1-8.2 0-16.1-8.8-19.8-13.5-3.8-4.8-11.1-12.2-19.4-12.2-3.8 0-7.7 1.5-11.7 5.6-11 11.3 2 47.6 35.5 55.8 4.7 1.2 9.3 1.7 13.7 1.7 26.7 0 46.6-19.8 52.7-40.5 7.1-24 4.6-64.4-14.4-76.7-1.5-1-3.4-1.5-5.3-1.5z" class="st42" fill="#7d7d65"/></g><path id="path6268" d="M290.11425 457.32051c6.5 1.7 19.4 2 29.8-6.6" fill="none" stroke="#7d7d65" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6270" d="M173.31425 408.82051c-3.7 5-10.1 7.9-16.3 7.2-6.2-.6-11.9-4.7-14.5-10.4-1.1 5.4-5.3 10.2-10.6 11.5-5.3 1.3-11.4-.7-14.8-5 1.6 13 12 22.7 16.5 35" fill="none" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6272" d="M263.31425 420.02051l-17.1 6.5c-5 1.9-10.6-.6-12.4-5.6-1.9-5 .6-10.6 5.6-12.4l17.1-6.5c5-1.9 10.6.6 12.4 5.6 1.9 4.9-.6 10.5-5.6 12.4z" fill="#e68a4c"/><path id="path6274" d="M625.31425 218.52051c7.3-2.8 14.1-4.3 19.2-3.8" class="st34" fill="none" stroke="#fbd7a3" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6276" d="M561.31425 267.62051c11.7-11.4 21.9-20.7 31.6-29.6 3.9-3.5 8.7-7.1 13.9-10.3" class="st34" fill="none" stroke="#fbd7a3" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6278" d="M471.21425 293.12051c15.7 1.4 33.6-.1 52.7-6.6" class="st34" fill="none" stroke="#fbd7a3" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6280" d="M361.61425 250.82051c19.9 3.5 36.4 12.2 56.1 23.6" class="st34" fill="none" stroke="#fbd7a3" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><g transform="translate(-77.185754 15.820514)" id="g6282"><path id="path6284" d="M311 486.9c-48 22-68 37-57 78s59 41 59 41-8 25 18 28 55-5 56-41-20-61-63-65" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6286" d="M313 605.9c10 2 25 2 25 2" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/><path id="path6288" d="M354.2 548.6l6.5 6.8c4.9 5.1 4.7 13.3-.4 18.2l-1.9 1.8c-5.1 4.9-13.3 4.7-18.2-.4l-6.5-6.8c-4.9-5.1-4.7-13.3.4-18.2l1.9-1.8c5.1-4.9 13.3-4.7 18.2.4z" fill="#fdd06e"/></g><path id="path6290" d="M396.81425 426.32051l-6.5 2.6c-4.9 1.9-10.5-.5-12.4-5.4l-.7-1.8c-1.9-4.9.5-10.5 5.4-12.4l6.5-2.6c4.9-1.9 10.5.5 12.4 5.4l.7 1.8c2 4.9-.5 10.5-5.4 12.4z" fill="#b9655a"/><path id="path6292" d="M218.51425 495.22051c1.8-14 .6-22.1.6-22.1" class="st2" fill="#fbc16c" stroke="#946f3a" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10"/></svg>
diff --git a/app/javascript/images/screen_interactions.svg b/app/javascript/images/screen_interactions.svg
new file mode 100644
index 0000000000000000000000000000000000000000..66a36f97804aadff16c4ff107dda424decc25740
--- /dev/null
+++ b/app/javascript/images/screen_interactions.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="1195.8" height="803"><path stroke-miterlimit="10" class="st99" d="M102.1 466.5c-6 5.8-11.8 5-18.2-.6-2.5-2.2-4.6.9-.6 4.9 4 4 13.5 8.3 22 .8" fill="#e09c5c" stroke="#946f3a" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M265.2 263.5h-59.8c-15 0-27.3 12.3-27.3 27.3v12.9c0 6.3 2.2 12.1 5.8 16.8-6.7 13.7-21.4 16.9-21.4 16.9 18.9 2.3 24.6-3.5 30.7-9.2 3.7 1.8 7.8 2.9 12.2 2.9h59.8c15 0 27.3-12.3 27.3-27.3v-12.9c.1-15.1-12.2-27.4-27.3-27.4z" fill="#fff" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st99" d="M146.3 472.5c-.1 11.9-2.4 21.1 7.9 21.2 10.3.1 13.2-2.5 13.1-10.1-.1-7.6-.6-21-.6-21" fill="#e09c5c" stroke="#946f3a" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st101" d="M131.8 365.8c-20.2 0-35.1 7.6-35.1 36v54.3c0 8 4.4 21.8 21.8 21.8h24.1c8.5 0 16.3-2.8 22.5-9.4 6.2-6.6 9.2-13.3 9.2-25.5v-46.6s20.4-.5 29.4-13.3c8.9-12.8 6.9-28.2 5.7-32.6 0 0 5.1-.5 4-4.4-1.1-3.9-7.3-3.3-10.1-1.1 0 0-1.6-1.8-7-1.7-5.4.1-3.7 6.2.7 6.7 0 0 2.4 13.8-4.6 18.7-7 4.9-21.4 6.6-29.8 2.7-8.5-3.7-11.3-5.6-30.8-5.6z" fill="#fbc16c" stroke="#946f3a" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path class="st4" d="M118.5 476.8c-20.1 0-20.6-18.5-20.6-20.6v-23.1c13 .1 18.8 1.5 18.8 12.4 0 13.2 2.2 19.8 13.9 19.8H162c1.7 0 3.4-.1 5-.7-.8 1-1.7 2.1-2.7 3.2-5.6 6-12.9 9-21.6 9z" fill="#e09c5c"/><path stroke-miterlimit="10" class="st101" d="M124.8 372.1c-9.6-2.9-14.7-4.9-11.8-13.3 2.9-8.4 17-6.6 24.7-2.7 0 0 4-2.4 6.3-3.3 2.3-.9 6.6-1.3 6.7 1.7 0 0 5.4.6 4.4 4.9 0 0 6.4 3.7-8.1 10.7M108.5 381.5c0-6.4-3.8-10.3-11.8-10.3s-14.8 7.5-13 18.7c1.8 11.2-4.3 19.9 2.8 24.9s14.4 1.9 16.7-1.9c0 0 7.6 2 7-9.9" fill="#fbc16c" stroke="#946f3a" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M137.3 395.8c-5.7 0-8.8 4.4-7.5 10.2 1.3 5.7 5 10 11.4 10.2 6.4.1 12.5-2.1 14.4-11.4 1.9-9.3-1.6-9.4-4.4-9.4-2.8 0-13.9.4-13.9.4z" fill="#544024" stroke="#3b3024" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M146.8 408.9c0-6.7-5.4-12.2-12.2-12.2-.6 0-1.1.1-1.7.1-2.8 1.6-4.1 5-3.2 9.1 1.3 5.7 5 10 11.4 10.2 1.1 0 2.2 0 3.3-.2 1.6-2 2.4-4.4 2.4-7z" fill="#693131" stroke="#381916" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st104" d="M151.1 402.5v-7.2c-3 0-13.8.4-13.8.4-4.5 0-7.4 2.8-7.8 6.8z" fill="#fff" stroke="#7d7d65" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st104" d="M116.2 410.7c6 5.8 14.3 5.8 18.1 2.6 3.8-3.2 5.8-11.4 2.7-12.2-3.1-.8-2.4 4.7-5.2 6.3-2.8 1.6-6 1.2-9-.7-2.9-1.9-5.9-3.2-7.4-1.4-1.3 2-.6 4 .8 5.4z" fill="#fff" stroke="#7d7d65" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M319.4 440.7c-5.7 6.2-14 6.6-18 3.6-4-3-6.4-11-3.4-12 3-1 2.7 4.5 5.5 6s6.1.9 8.9-1.1c2.8-2 5.7-3.6 7.3-1.7 1.6 1.9 1.1 3.8-.3 5.2z" fill="none" stroke="#000" stroke-width=".571"/><path stroke-miterlimit="10" class="st101" d="M104.3 415.3l-20.5.1s-.7-3.4-3.8-2.9c-3.1.5-3.8 2.3-3.9 3.4 0 0-6.8.4-6.9 7.2-.1 6.8 4.9 9.5 12.1 9.1 7.2-.4 24.4 0 24.4 0" fill="#fbc16c" stroke="#946f3a" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st99" d="M105.4 472.5c-.1 11.9-2.4 21.1 7.9 21.2 10.3.1 13.2-2.5 13.1-10.1-.1-7.6-.2-10.4-.2-10.4" fill="#e09c5c" stroke="#946f3a" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path d="M122.7 399.8c-.9 0-1.6-.7-1.6-1.6v-10.9c0-.9.7-1.6 1.6-1.6.9 0 1.6.7 1.6 1.6v10.9c0 .9-.7 1.6-1.6 1.6z" fill="#402f19"/><path stroke-miterlimit="10" class="st106" d="M518.8 297c-6.9-8.5-22.1-16.7-42.9-6.4-20.8 10.3-26.2 38-14.9 56.5 11.3 18.5 14.4 22.6 14.4 22.6v46.7c0 9.8 2.8 13.3 10 13.3s11.3-2.8 11.3-9.8v-10.5h29.5v11c0 4.3 2.6 9 9.5 9s9.8-2.3 9.8-11.8V355s.8-27.4-26.7-58z" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path class="st4" d="M485.4 427.9c-6.2 0-8.2-2.8-8.2-11.6V369l-.4-.5s-2-2.7-8.5-13.1c.1-1.4.2-2.8.1-4.1l13 17.2v22c0 5.2 1.1 11.2 9.9 11.2h52.3v15.8c0 9-2.6 10-8 10-7.2 0-7.7-5.5-7.7-7.2v-12.7H495v12.3c0 5.5-3 8-9.6 8z" fill="#e09c5c"/><path d="M504.6 170.3h206.2v203.5H504.6z" stroke-miterlimit="10" stroke="#3b3024" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path d="M477.8 330.1c-.8 0-1.6-.4-2-1.1l-5.3-9c-.3-.5-.4-1.2-.2-1.7.2-.6.5-1.1 1.1-1.4 1.1-.6 2.5-.3 3.2.8l5.3 9c.6 1.1.3 2.5-.8 3.2-.5.1-.9.2-1.3.2z" fill="#141a1c"/><path stroke-miterlimit="10" class="st108" d="M264.8 453c-7.2.9-16.7-.7-21.6-1.8-4.9-1.1-7.8 4.3-8.5 9.5-.7 5.2 11.7 14.1 32.7 8.7M333 450.2c13.1 4.1 22.2 11.7 22 20.3-.2 8.6-9.6 14.2-16.5 15.5-6.9 1.3-9.8-6.1-8.9-11.1.9-5 3.4-6.6 3.4-6.6M328 465.6c5 2.6 10.1 5.4 10.1 5.4M334 412c0-6.4 3.8-10.3 11.8-10.3s14.8 7.5 13 18.7c-1.8 11.2 4.3 19.9-2.8 24.9-7.1 4.9-14.4 1.9-16.7-1.9 0 0-7.6 2-7-9.9" fill="#fbe6c6" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st108" d="M298.1 395.3c-29.7-.3-34.4 7.9-42 14.4-7.6 6.6-17.6 18.8-36.6 19.5 0 0-2.5-3.5-5.2-1s-2.2 5.9-.3 7.2c0 0-3.7 3.7.2 7.6 3.9 3.9 7.2 0 7.2 0s14.4 1.3 25.9-4c11.4-5.4 15.1-3.3 15.1-3.3v50.4c0 15.8 7.2 22 25.9 22s36.8 1.7 44.5-6.2c7.7-7.9 6.4-19.2 5.9-29.2s0-28.1 0-43.5c0-15.4-1.4-33.6-40.6-33.9z" fill="#fbe6c6" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st109" d="M310.3 505.6c0 4.8-.5 6.6-.2 10.1-1.6 1.1-2.2 3-1.7 4.6.6 2 3.6 4 9.9 3.9 10.4.1 13.2-2.5 13.1-10.1-.1-3.5-.2-8.2-.3-12.2" fill="#dcceb5" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path d="M304.5 507c-2.6 0-5.1 0-7.9-.1-2.8 0-5.6-.1-8.4-.1-18 0-24.7-5.7-24.7-20.9 0-2.5 4.3-4.8 9-4.8 2.3 0 6.6.6 9.2 4.3 3.8 5.2 8.9 7.1 16.3 7.1 4.5 0 14.5.2 17.9-2.4 4.5-3.3 5.8-7.9 13.3-9.6 3-.7 5.6-1.2 8.6-.4.2 9.3-1.3 17.2-5.9 20.8-5.5 4.4-14.5 6.1-27.4 6.1z" fill="#dcceb5"/><path stroke-miterlimit="10" class="st108" d="M311.9 402.8c7-.1 10.7-4.4 10.2-8.6-.6-4.1-3.5-9.9-16.6-9.2-5.8.3-8.7 4.1-11.5 4.1-2.8-.1-8.3-8.1-13.1-7.6-4.8.5-5.1 3.9-4.3 5.5 0 0-4.3 1.3-1.9 6.9 2.4 5.6 7.3 7.5 12.1 8.1" fill="#fbe6c6" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st109" d="M271.7 503.1c0 4.8-.5 9.2-.2 12.7-1.6 1.1-2.2 3-1.7 4.6.6 2 3.6 4 9.9 3.9 10.4.1 13.2-2.5 13.1-10.1 0-2.9-.1-3.7-.2-7.2" fill="#dcceb5" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st106" d="M463.1 323.1c-3.8-5.7-8.6-7.6-16.5-3.7-7.9 3.9-8.7 14.8-4.6 21 4.2 6.3 4.8 11.2 3.8 15.8-1 4.6.5 7.1 3.7 8 3.2.9 5.2-1.1 5.2-1.1s11.2 1.1 12.4-8c1.2-9.1-.2-12.9-.2-12.9" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M454.7 363.1c2-2.5 2-7.6 2-7.6" fill="none" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st106" d="M462.8 306.7c-7.3-3.2-9.2-12.8-2.8-17 6.4-4.2 13.3-4.3 13.3-4.3s7.1-12.2 11.7-12.6c4.6-.4 6 2.7 5.2 5.2 0 0 5.9-1.1 6 3.8.1 5-2.6 7.8-6.4 10.6" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M486.8 340.8c7.3 2.2 15.1 2.2 19.6-4.9 4.5-7.1 6.9-14.3 2.9-15.8s-5.4 2-7.2 6.5c-1.8 4.5-5.1 6-10.8 5.1-5.7-.9-7.7 0-8.1 2.7-.4 2.7.3 5.3 3.6 6.4z" fill="#fff" stroke="#4a493c" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M627.8 211.5c.7-8.6 12.3-17.4 29.3-11.5 17 5.9 30.2 19.1 26.7 44.7 0 0 13.1 53.9 13.6 80l-31.7 1.6 1.1-57.3c0 .1-50.3-41.3-39-57.5z" fill="#fbdeb5" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st113" d="M666.8 269.1c-.4-14.1.7-22.5.7-22.5" fill="#fbc16c" stroke="#946f3a" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M628.7 208.6c6.4-7.9 18.4-6.8 28.2-1.2 9.9 5.5 15.4 12 15.4 12" fill="none" stroke="#946f3a" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st115" d="M622.4 215.4c-2.1-4.9 9.9-8.8 18.2-3.6 8.3 5.2 18.6 15.2 18.5 26.7-.1 11.5-11.2 9.1-11.2 9.1s-25.1-31.4-25.5-32.2z" fill="#fbe6c6" stroke="#668794" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st106" d="M607 294c4.3 13.7 10.6 20.3 10.6 20.3l31.8-16.4-7.9-12.1z" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path class="st45" d="M657.1 258.2c0 25.5-21.2 42.3-45.8 44-28.8 2-43.4-18.5-43.4-44s20-46.1 44.6-46.1 44.6 20.6 44.6 46.1z" fill="#fbc16c"/><path stroke-miterlimit="10" class="st106" d="M619.4 301.1c-2.6.6-5.3.9-8.1 1.1-28.8 2-43.4-18.5-43.4-44s20-46.1 44.6-46.1 44.6 20.7 44.6 46.1c0 7.1-1.6 13.5-4.5 19.1" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st106" d="M581.5 247.7c-18.4 13.4-32.3 13.5-41.8 4.6 0 0 1.6-5.8-4.2-4.8-5.8 1-7.8 7.2-5.4 10.4 0 0-2.6 4.2-.4 8.4s8 2.8 8 2.8 8.4 9.4 20.3 9.4 21.1-3.4 25.9-8.4" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M599.2 282.6c-.3-2.5-1.6-4.8-3.6-6.3s-4.6-2.2-7-1.8c-.9.1-1.9.5-2.3 1.3-1.3-.4-2.6-.7-3.9-.5-1.3.2-2.6.8-3.3 2-.7 1.1-.7 2.7.2 3.7-.4 2.4.3 5 2.3 6.4.8.5 1.7.9 2.6 1.1 2.1.6 4.4.7 6.5 0 1.3-.4 2.4-1.1 3.5-1.8 1.7-1.2 3.7-2.3 5-4.1z" fill="#a34c4c" stroke="#47271c" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M592.6 281.5c-2.1 2.2-5.4 3.2-8.4 2.7-1.7-.3-3.5-1.3-4-3 1.8-1.4 4-2.1 6.3-2.1 2.2 0 4.3 1 6.1 2.4z" fill="#fbe6c6" stroke="#47271c" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><circle cx="613.1" cy="271.9" r="7.2" fill="#a34c4c"/><path stroke-miterlimit="10" class="st118" d="M594.6 250.6c2.1 4.5 3.4 5.7 6.3 6.6 2.9.9 7.5-.6 9.4-3.2 0 0-2.2-3.7-7.2-4.9-5-1.1-8.5 1.5-8.5 1.5zM580.5 247.2s.9-4.5-8.9-7.4c-1.2 2.8-2.1 5.8-2.7 8.9 6.5 1.3 9.4.8 11.6-1.5z" fill="#fbe6c6" stroke="#946f3a" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st106" d="M642.7 250.6c-5 13.3-5.7 28.4-1.9 33.9 3.9 5.6 9.1 4.2 9.9 1.1 0 0 .7 5.1 6.6 5.7 5.8.6 10.3-6.8 10.2-19-.1-12.2-3.7-21-12.9-21.9-9.2-.9-11.9.2-11.9.2z" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M574.6 233.9c12.3-2.5 26.9-2.1 42.9 7.1s30.1 14 39.6 14.9c-1.1-24.5-20.6-44-44.5-44-16.1.1-30.2 8.9-38 22z" fill="#51a1b5" stroke="#31446e" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st113" d="M596.6 240.8c1.7-1 3.7-1.5 5.6-1.6M605.7 238.9c1 0 1.9.2 2.8.5M576.4 235.5c1.8.3 3.5 1.3 4.8 2.6" fill="#fbc16c" stroke="#946f3a" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st120" d="M577.6 242.5c-.3.2-.6.4-.9.7-1.5 1.7-1.4 4.3.2 5.9 1.5-.3 2.6-1 3.6-2 0 .1.5-2.2-2.9-4.6zM610.3 254s-1.6-2.8-5.3-4.3c-.4.2-.9.5-1.2.9-1.6 1.8-1.4 4.5.3 6.1.2.2.5.4.7.5 2.2-.4 4.4-1.6 5.5-3.2z" fill="#4d3b21" stroke="#2b2111" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st106" d="M683.8 244.7c-2.3-7.7-5.4-11.6-5.4-11.6" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st121" d="M611.3 323.1c-3.1 9.1-5.8 21.9 2 32.1l-2.2 11.4 80.7 2.3s-1-32.5-15.5-42.8c-14.4-10.4-15.9-11.5-18.9-15-3.1-3.5-5.9-9.7-5.9-9.7z" fill="#876a4d" stroke="#3b3024" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st121" d="M649.1 296.5c-18 2.9-31.5 11.9-38.2 22.5-3.8 6-3.2 10.1-3.2 10.1l47.2-28zM605.7 365.5c.5-12.8 3.5-34.8 20.8-36.8s39.3 3.1 55.7 38.2z" fill="#876a4d" stroke="#3b3024" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M497.8 163.6v218.9h218.9V163.6zm201.9 201.9H514.8V180.6h184.9z" fill="#594726" stroke="#45331b" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path d="M504.6 170.3h206.2v206.2H504.6z" stroke-miterlimit="10" fill="none" stroke="#45331b" stroke-width="2.674" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M651.5 312.2c6.5.1 10.6 4.6 10.6 4.6" fill="none" stroke="#3b3024" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st113" d="M679.6 325.8c-2.9-26.5-7.3-51.7-7.3-51.7M683.3 325.3l-.6-27.8" fill="#fbc16c" stroke="#946f3a" stroke-width="1.782" stroke-linecap="round" stroke-linejoin="round"/><circle stroke-miterlimit="10" class="st115" cx="649.4" cy="298" r="7.7" fill="#fbe6c6" stroke="#668794" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M607.4 236.3c3.3 1.2 6.6 2.8 10 4.7 16 9.2 30.1 14 39.6 14.9-.7-15.2-8.5-28.5-20.1-36.4-11.9 1.5-22.4 7.8-29.5 16.8z" fill="#31446e" stroke="#31446e" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st106" d="M495.1 347c5.7 4.6 14.7 8.5 20.1 6.6 7.7-2.7 12.7-4.6 15.8 2.2 3.1 6.8-1.9 10.8-10.1 15.2-9.9 5.2-18.6.3-26.3-3.7M570.7 380.9c0 4.9-3.9 7-8.8 7s-8.8-2.2-8.8-7 3.9-7.7 8.8-7.7 8.8 2.9 8.8 7.7z" fill="#fbc16c" stroke="#946f3a" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M593.5 225.5c8.4.5 16.9 1.8 28.6 7.8" fill="none" stroke="#31446e" stroke-width="2.674" stroke-linecap="round" stroke-linejoin="round"/><path d="M598.6 175.5h3.6M616.3 175.5h64M588.7 175.5h5.6M513.3 175.5H579" stroke-miterlimit="10" class="st127" fill="none" stroke="#fbf0d3" stroke-width="2.674" stroke-linecap="round" stroke-linejoin="round"/><path class="st72" d="M262.8 284.5h-54.6c-1.9 0-3.4-1.5-3.4-3.4s1.5-3.4 3.4-3.4h54.6c1.9 0 3.4 1.5 3.4 3.4s-1.5 3.4-3.4 3.4zM262.8 301.4h-54.6c-1.9 0-3.4-1.5-3.4-3.4s1.5-3.4 3.4-3.4h54.6c1.9 0 3.4 1.5 3.4 3.4 0 1.8-1.5 3.4-3.4 3.4zM262.8 318.2h-54.6c-1.9 0-3.4-1.5-3.4-3.4s1.5-3.4 3.4-3.4h54.6c1.9 0 3.4 1.5 3.4 3.4s-1.5 3.4-3.4 3.4z" fill="#4a4439"/><path stroke-miterlimit="10" class="st108" d="M273.9 412c0-6.4 3.8-10.3 11.8-10.3s14.8 7.5 13 18.7c-1.8 11.2 4.3 19.9-2.8 24.9-7.1 4.9-14.4 1.9-16.7-1.9 0 0-7.6 2-7-9.9" fill="#fbe6c6" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path d="M534.8 202.3h45.1M534.8 313.4h45.1M550.1 330.7h29.8M534.8 348.4h45.1M534.8 218.4h11.8" stroke-miterlimit="10" class="st128" fill="#fbe6c6" stroke="#28353b" stroke-width="7.13" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st101" d="M172.3 427.6c11.6-.6 21.6-4.6 26.7-9.3 5.8-5.3 8.9-10.5 3.7-15.1-5.1-4.5-10.1-.1-10.1-.1s-2-3.1-5-.8-.8 4.5-.8 4.5-3.6 5-14.9 5.5" fill="#fbc16c" stroke="#946f3a" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path class="st31" d="M117 400.6l-3.5.6c-1 .2-2-.5-2.1-1.5-.2-1 .5-2 1.5-2.1l3.5-.6c1-.2 2 .5 2.1 1.5.2 1-.4 2-1.5 2.1zM476.8 338l-5.4.9c-1.6.3-3.1-.8-3.3-2.4-.3-1.6.8-3.1 2.4-3.3l5.4-.9c1.6-.3 3.1.8 3.3 2.4.3 1.6-.8 3.1-2.4 3.3z" fill="#e68a4c"/><path stroke-miterlimit="10" class="st129" d="M187.7 375.8c.7-.2 1-.4 1.6-.7M182.5 377.2c.9-.2.4 0 1.2-.2M170.2 377.4c2.2.3 4.4.4 6.6.4M156.1 373.4c2.4 1.1 5 2 7.7 2.7" fill="none" stroke="#fbd7a3" stroke-width="2.853" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#946f3a" fill="#e09c5c" class="st130" d="M943 464.9c-8.7 8.4-17 7.2-26.3-.8-3.6-3.1-6.6 1.3-.8 7.1s19.4 12 31.7 1.2M1006.7 473.5c-.2 17.1-3.5 30.4 11.5 30.6 15 .2 19.1-3.7 18.9-14.6-.2-11-.8-30.2-.8-30.2"/><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#946f3a" fill="#fbc16c" class="st131" d="M985.8 319.6c-29.1 0-50.6 10.9-50.6 51.9v78.4c0 11.6 6.3 31.4 31.4 31.4h34.7c12.2 0 23.5-4 32.4-13.6 8.9-9.6 13.2-19.2 13.2-36.7v-67.1s29.4-.7 42.3-19.2c12.9-18.5 9.9-40.7 8.3-47 0 0 7.4-.7 5.8-6.3-1.6-5.6-10.5-4.7-14.6-1.6 0 0-2.3-2.6-10.1-2.4-7.8.2-5.3 9 1 9.6 0 0 3.5 20-6.6 27s-30.9 9.5-43 3.9c-12.1-5.5-16.1-8.3-44.2-8.3z"/><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="4.327" stroke="#402f19" fill="none" class="st132" d="M983.3 370.5c8.6 5.9 19.2 7.4 26.8.7"/><path fill="#e09c5c" class="st4" d="M966.6 479.7c-28.9 0-29.8-26.7-29.8-29.8v-33.3c18.8.2 27.1 2.2 27.1 17.9 0 19 3.1 28.6 20.1 28.6h45.2c2.5 0 4.9-.1 7.2-1.1-1.1 1.5-2.4 3-3.9 4.6-8.1 8.7-18.6 13-31.2 13h-34.7z"/><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#946f3a" fill="#fbc16c" class="st131" d="M975.8 328.7c-13.8-4.1-21.2-7-17.1-19.1 4.1-12.1 24.5-9.5 35.6-3.9 0 0 5.8-3.4 9.1-4.7 3.3-1.3 9.5-1.9 9.7 2.4 0 0 7.8.8 6.4 7 0 0 9.3 5.3-11.7 15.4M952.2 342.3c0-9.3-5.4-14.8-17-14.8s-21.4 10.8-18.7 27c2.7 16.2-6.2 28.7 4 35.9 10.2 7.2 20.8 2.7 24.1-2.7 0 0 11 2.9 10-14.3"/><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#7d7d65" fill="#fff" d="M963.3 384.4c8.7 8.4 20.6 8.4 26.1 3.8 5.5-4.6 8.4-16.4 4-17.5-4.4-1.2-3.5 6.7-7.5 9.1-4 2.3-8.7 1.7-12.9-1-4.2-2.7-8.5-4.7-10.6-2-2.1 2.7-1.1 5.6.9 7.6z"/><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#946f3a" fill="#e09c5c" class="st130" d="M947.8 473.5c-.2 17.1-3.5 30.4 11.5 30.6 15 .2 19.1-3.7 18.9-14.6-.2-11-.3-15-.3-15"/><path fill="#e68a4c" class="st31" d="M965.4 369.8l-6.7 1.1c-1 .2-2-.5-2.1-1.5l-.3-1.6c-.2-1 .5-2 1.5-2.1l6.7-1.1c1-.2 2 .5 2.1 1.5l.3 1.6c.2.9-.5 1.9-1.5 2.1z"/><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="4.115" stroke="#fbd7a3" fill="none" class="st134" d="M1066.5 334c1-.4 1.4-.5 2.4-1M1059 336.1c1.2-.2.5 0 1.7-.3M1041.1 336.4c3.1.4 6.3.6 9.5.5M1020.8 330.6c3.4 1.5 7.2 2.9 11.1 3.9"/><path stroke-miterlimit="10" class="st135" d="M275.1 402.4c.7-.3 1.3-.5 1.9-.8M269.6 405.1c.9-.5.9-.6 1.8-1.1M261.8 410.5c1.6-1.2 2.5-1.9 4.1-2.9M254.1 417.8c1.2-1.3 2.6-2.6 4-3.9" fill="none" stroke="#fff" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st136" d="M519.2 357.7c.9-.3 1.8-.7 2.7-1.1M508.6 358.8c1.5.2 2.9.3 4.5.1M495 353.7c2.7 1.4 5.2 2.7 7.7 3.6" fill="none" stroke="#fbd7a3" stroke-width="4.456" stroke-linecap="round" stroke-linejoin="round"/><path d="M705.7 298.9v3M705.7 290.9v2.6M705.7 243.7v38.4" stroke-miterlimit="10" class="st137" fill="none" stroke="#bf9649" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path d="M700.3 206.8L712 226l19.7 11.1-19.3 11.8-11.1 19.6-11.8-19.2-19.6-11.1 19.3-11.8zM687.9 176l8.4-4.9 5-8.4 4.9 8.4 8.4 5-8.4 4.9-5 8.4-4.9-8.4z" class="st33" fill="#fff"/><path d="M509.2 246.6v-2.9M509.2 254.7V252M509.2 301.9v-38.4" stroke-miterlimit="10" class="st137" fill="none" stroke="#bf9649" stroke-width="3.565" stroke-linecap="round" stroke-linejoin="round"/><path d="M454.6 433.1h255.3v95.6H454.6z" fill="#587faa"/><path d="M708.8 434.1v93.6H455.5v-93.6h253.3m2-2H453.5v97.6h257.3z"/><path d="M708.81 446.053v9.1h-253.2v-9.1z" class="st82" fill="#2d3f68"/><path d="M455.3 446.1h255.5M462.3 463.4v2.2M462.3 446.1v13.1M468.4 463.4v2.2M468.4 446.1v13.1" stroke-miterlimit="10" class="st80" fill="#587faa" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M458.9 435.7h246.8" stroke-miterlimit="10" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st158" d="M714.6 483.2c0-6.8-2.8-11.9-6.9-11.9-4.1 0-6.7 4.1-6.7 11.9v17.4c0 4.8.5 11.1 6.8 11.1s4.8-17.9 4.8-17.9M767.3 483.2c0-6.8 2.8-11.9 6.9-11.9 4 0 6.7 4.1 6.7 11.9v17.4c0 4.8-.5 11.1-6.8 11.1s-4.8-17.9-4.8-17.9" fill="#f4a679" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st158" d="M801.4 500.9c-2.4-2.8-6.8-3.1-9.7-.8-6.2 4.9-9.9 7.4-16.1 11V500c0-.6-.1-1.1-.1-1.7.1-.9.1-1.9.1-2.9 0-18.7-15.2-30.7-33.9-30.7s-33.9 12-33.9 30.7c0 1 0 1.9.1 2.9-.1.5-.1 1.1-.1 1.7v9.7c-5.8-3.4-9.4-5.8-15.3-10.6-2.9-2.3-7.2-2-9.7.8-2.4 2.8-1.9 7.3 1.3 9.9 7.6 6 11.7 8.7 20.1 13.4 1.2.7 2.4 1 3.6 1v25.6c0 .4 0 .9.1 1.3 0 .3-.1.6-.1.9v22.6c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-12.8h29.3v12.8c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8V552c0-.3 0-.6-.1-.9 0-.4.1-.9.1-1.3V525c1.5.2 3-.1 4.4-.9 8.4-4.7 12.5-7.4 20.1-13.4 2.9-2.4 3.4-6.9 1-9.8z" fill="#f4a679" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path d="M722.6 561.9h40.7" stroke-miterlimit="10" class="st108" fill="#fbe6c6" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st158" d="M737.3 557.4c3.9 9.1 16.6 9.5 23.8 3.7 2.8-2.2 2.4-4.5-1.9-3.7-4.3.7-10.6 3.9-15.6-2M724.6 471.3c-1.8-7.5 1.7-14.4 13.4-12.2 2.7.5 4.8 1.5 4.8 1.5s6-1 11.2-2.8c5.2-1.8 9 .5 9.9 5.4.8 4.9-1.5 8.3-8.9 9.7" fill="#f4a679" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st159" d="M625.2 484.8c0-6.8-2.8-11.9-6.9-11.9-4 0-6.7 4.1-6.7 11.9v17.4c0 4.8.5 11.1 6.8 11.1s4.8-17.9 4.8-17.9M677.9 484.8c0-6.8 2.8-11.9 6.9-11.9 4.1 0 6.7 4.1 6.7 11.9v17.4c0 4.8-.5 11.1-6.8 11.1s-4.8-17.9-4.8-17.9" fill="#965e8c" stroke="#5c3556" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st159" d="M687.5 513.4l-1.3 1.6v-13.3c0-.6-.1-1.1-.1-1.7.1-.9.1-1.9.1-2.9 0-18.7-15.2-33.9-33.9-33.9s-33.9 15.2-33.9 33.9c0 1 0 1.9.1 2.9-.1.5-.1 1.1-.1 1.7v11.7c-13.2 3.2-16 17.8 0 24.1v14c0 .4 0 .9.1 1.3 0 .3-.1.6-.1.9v22.6c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-12.7h29.3v12.8c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-22.6c0-.3 0-.6-.1-.9 0-.4.1-.9.1-1.3v-13.5c.4-.1.9-.3 1.3-.5 15.8-6.3 13-21-.3-24.2z" fill="#965e8c" stroke="#5c3556" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path d="M632.8 563.6h40.7" stroke-miterlimit="10" fill="#fbe6c6" stroke="#5c3556" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st161" d="M677.3 479.1c.8 1.1 1.5 2.2 2.1 3.4M671.8 473.2c.9.8 1.8 1.6 2.7 2.5M633 473c5.3-4.2 12-6.7 19.2-6.7 6.4 0 12.3 2 17.3 5.3" fill="none" stroke="#b895a6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M618.3 537.5v-10.4l3-2.1M686.2 538v-11.6l-3-2.1" stroke-miterlimit="10" class="st162" fill="none" stroke="#5c3556" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path class="st163" d="M536.7 483.2c0-6.8-2.8-11.9-6.9-11.9-4.1 0-6.7 4.1-6.7 11.9v17.4c0 4.8.5 11.1 6.8 11.1s4.8-17.9 4.8-17.9M589.4 483.2c0-6.8 2.8-11.9 6.9-11.9 4 0 6.7 4.1 6.7 11.9v17.4c0 4.8-.5 11.1-6.8 11.1s-4.8-17.9-4.8-17.9" fill="#fbe6c6"/><path stroke-miterlimit="10" class="st108" d="M623.5 500.9c-2.4-2.8-6.8-3.1-9.7-.8-6.2 4.9-9.9 7.4-16.1 11V500c0-.6-.1-1.1-.1-1.7.1-.9.1-1.9.1-2.9 0-18.7-15.2-30.7-33.9-30.7s-33.9 12-33.9 30.7c0 1 0 1.9.1 2.9-.1.5-.1 1.1-.1 1.7v9.7c-5.8-3.4-9.4-5.8-15.3-10.6-2.9-2.3-7.2-2-9.7.8-2.4 2.8-1.9 7.3 1.3 9.9 7.6 6 11.7 8.7 20.1 13.4 1.2.7 2.4 1 3.6 1v25.6c0 .4 0 .9.1 1.3 0 .3-.1.6-.1.9v22.6c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8v-12.8h29.3v12.8c0 3.2 2.6 5.8 5.8 5.8h7.8c3.2 0 5.8-2.6 5.8-5.8V552c0-.3 0-.6-.1-.9 0-.4.1-.9.1-1.3V525c1.5.2 3-.1 4.4-.9 8.4-4.7 12.5-7.4 20.1-13.4 2.9-2.4 3.4-6.9 1-9.8zM544.3 561.9H585" fill="#fbe6c6" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st108" d="M544.5 472.5c-3.4-7.4 3.2-16.2 17.7-12.8 0 0 16.5-3.7 19.8-2.6 2.7 1 3.2 3.5 0 4.8 0 0 3.2 3.7-.8 5.3 0 0 1.1 4.3-3.6 5.3s-13.4 0-13.4 0M574.1 466.6c3.2-.1 7.1.6 7.1.6M572.6 461.9s4.8-1 9.3 0" fill="#fbe6c6" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="4.327" stroke="#402f19" fill="none" class="st132" d="M966.2 358.4c3.2-4.1 7.7-4.8 10.8 0"/><g><path d="M1086.8 435.8v-67.5L1048 354l-60.6 14.4v69.2l40.2 17.1z" stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#552814" fill="#e14741" class="st164"/><path d="M1048 354l-60.6 14.4 40.1 13 59.3-13.1zM1086.8 368.3l-59.3 13.1.1 73.3 59.2-15.1z" stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#552814" fill="#e14741" class="st164"/></g><path stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#946f3a" fill="#fbc16c" class="st131" d="M950.1 415.4c13 12.2 29.5 18.9 48.8 15.1 7.6-1.5 9.4-19.1-3.3-19.4 0 0-1.8-6.5-6.1-5.7-4.3.8-2.4 5.7-2.4 5.7s-18.6-4.6-25.9-12.2"/><path stroke-miterlimit="10" class="st109" d="M330.1 497c6 5.8 11.8 5 18.2-.6 2.5-2.2 4.6.9.6 4.9-4 4-13.5 8.3-22 .8" fill="#dcceb5" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" d="M727.9 463.2c2.2-1.9 6.1-3.7 14.1 0 0 0 8.5-1.3 13.5-3.3" fill="none" stroke="#f7ceb2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M1051.4 416.2l-9.2-5.6 12.1-4 4.7-12.3 4.7 10.1 12.1-2.1-9.2 10.2 2.8 11-10.4-3.7-10.4 8.8z" fill="#fbc16c" class="st45"/><path stroke-miterlimit="10" class="st108" d="M559.4 557.4c3.9 9.1 16.6 9.5 23.8 3.7 2.8-2.2 2.4-4.5-1.9-3.7-4.3.7-10.6 3.9-15.6-2" fill="#fbe6c6" stroke="#668794" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><path stroke-miterlimit="10" class="st159" d="M644.8 557.4c3.9 9.1 16.6 9.5 23.8 3.7 2.8-2.2 2.4-4.5-1.9-3.7-4.3.8-10.6 3.9-15.6-2" fill="#965e8c" stroke="#5c3556" stroke-width="2.283" stroke-linecap="round" stroke-linejoin="round"/><g transform="translate(-18.4)"><circle r="38.4" cy="585.9" cx="616.3" class="st82" fill="#2d3f68"/><path class="st33" d="M607.7 585.6v7.9h12.5l4.5 6.1h-22.8v-14h-6.5l9.2-10.9 9.4 10.9zM626.5 587.6v-7.9H614l-4.5-6.1h22.8v13.9l6.5.1-9.3 10.9-9.3-10.9z" fill="#fff"/></g><g transform="translate(-67.403)"><circle r="38.4" cy="582.2" cx="265.5" class="st82" fill="#2d3f68"/><path d="M283.1 580c-4.8-8.9-19.9-8.5-25.1-8.1V564l-13.5 13.5L258 591v-7.6c16.4 0 22.9.4 21.9 16.7 0 .2 9-9.3 3.2-20.1z" class="st33" fill="#fff"/></g><g transform="translate(-.3)"><circle r="38.4" cy="582.2" cx="996.8" class="st82" fill="#2d3f68"/><path class="st33" d="M1005.4 586.9l3.2 13.4-11.8-7.2-11.8 7.2 3.2-13.4-10.4-9 13.7-1.1 5.3-12.8 5.3 12.8 13.8 1.1z" fill="#fff"/></g><path d="M1032 385l51-12" stroke-miterlimit="10" stroke-linejoin="round" stroke-linecap="round" stroke-width="3.292" stroke="#e69985" fill="none"/></svg>
\ No newline at end of file
diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js
index c9e4afcfc3d8e51b61c0f5274bbc80cf95092954..d4a824e2c9d646c4030b9c09715408e3df05a710 100644
--- a/app/javascript/mastodon/actions/accounts.js
+++ b/app/javascript/mastodon/actions/accounts.js
@@ -30,6 +30,14 @@ export const ACCOUNT_UNMUTE_REQUEST = 'ACCOUNT_UNMUTE_REQUEST';
 export const ACCOUNT_UNMUTE_SUCCESS = 'ACCOUNT_UNMUTE_SUCCESS';
 export const ACCOUNT_UNMUTE_FAIL    = 'ACCOUNT_UNMUTE_FAIL';
 
+export const ACCOUNT_PIN_REQUEST = 'ACCOUNT_PIN_REQUEST';
+export const ACCOUNT_PIN_SUCCESS = 'ACCOUNT_PIN_SUCCESS';
+export const ACCOUNT_PIN_FAIL    = 'ACCOUNT_PIN_FAIL';
+
+export const ACCOUNT_UNPIN_REQUEST = 'ACCOUNT_UNPIN_REQUEST';
+export const ACCOUNT_UNPIN_SUCCESS = 'ACCOUNT_UNPIN_SUCCESS';
+export const ACCOUNT_UNPIN_FAIL    = 'ACCOUNT_UNPIN_FAIL';
+
 export const FOLLOWERS_FETCH_REQUEST = 'FOLLOWERS_FETCH_REQUEST';
 export const FOLLOWERS_FETCH_SUCCESS = 'FOLLOWERS_FETCH_SUCCESS';
 export const FOLLOWERS_FETCH_FAIL    = 'FOLLOWERS_FETCH_FAIL';
@@ -137,12 +145,14 @@ export function fetchAccountFail(id, error) {
 export function followAccount(id, reblogs = true) {
   return (dispatch, getState) => {
     const alreadyFollowing = getState().getIn(['relationships', id, 'following']);
-    dispatch(followAccountRequest(id));
+    const locked = getState().getIn(['accounts', id, 'locked'], false);
+
+    dispatch(followAccountRequest(id, locked));
 
     api(getState).post(`/api/v1/accounts/${id}/follow`, { reblogs }).then(response => {
       dispatch(followAccountSuccess(response.data, alreadyFollowing));
     }).catch(error => {
-      dispatch(followAccountFail(error));
+      dispatch(followAccountFail(error, locked));
     });
   };
 };
@@ -159,10 +169,12 @@ export function unfollowAccount(id) {
   };
 };
 
-export function followAccountRequest(id) {
+export function followAccountRequest(id, locked) {
   return {
     type: ACCOUNT_FOLLOW_REQUEST,
     id,
+    locked,
+    skipLoading: true,
   };
 };
 
@@ -171,13 +183,16 @@ export function followAccountSuccess(relationship, alreadyFollowing) {
     type: ACCOUNT_FOLLOW_SUCCESS,
     relationship,
     alreadyFollowing,
+    skipLoading: true,
   };
 };
 
-export function followAccountFail(error) {
+export function followAccountFail(error, locked) {
   return {
     type: ACCOUNT_FOLLOW_FAIL,
     error,
+    locked,
+    skipLoading: true,
   };
 };
 
@@ -185,6 +200,7 @@ export function unfollowAccountRequest(id) {
   return {
     type: ACCOUNT_UNFOLLOW_REQUEST,
     id,
+    skipLoading: true,
   };
 };
 
@@ -193,6 +209,7 @@ export function unfollowAccountSuccess(relationship, statuses) {
     type: ACCOUNT_UNFOLLOW_SUCCESS,
     relationship,
     statuses,
+    skipLoading: true,
   };
 };
 
@@ -200,6 +217,7 @@ export function unfollowAccountFail(error) {
   return {
     type: ACCOUNT_UNFOLLOW_FAIL,
     error,
+    skipLoading: true,
   };
 };
 
@@ -694,3 +712,69 @@ export function rejectFollowRequestFail(id, error) {
     error,
   };
 };
+
+export function pinAccount(id) {
+  return (dispatch, getState) => {
+    dispatch(pinAccountRequest(id));
+
+    api(getState).post(`/api/v1/accounts/${id}/pin`).then(response => {
+      dispatch(pinAccountSuccess(response.data));
+    }).catch(error => {
+      dispatch(pinAccountFail(error));
+    });
+  };
+};
+
+export function unpinAccount(id) {
+  return (dispatch, getState) => {
+    dispatch(unpinAccountRequest(id));
+
+    api(getState).post(`/api/v1/accounts/${id}/unpin`).then(response => {
+      dispatch(unpinAccountSuccess(response.data));
+    }).catch(error => {
+      dispatch(unpinAccountFail(error));
+    });
+  };
+};
+
+export function pinAccountRequest(id) {
+  return {
+    type: ACCOUNT_PIN_REQUEST,
+    id,
+  };
+};
+
+export function pinAccountSuccess(relationship) {
+  return {
+    type: ACCOUNT_PIN_SUCCESS,
+    relationship,
+  };
+};
+
+export function pinAccountFail(error) {
+  return {
+    type: ACCOUNT_PIN_FAIL,
+    error,
+  };
+};
+
+export function unpinAccountRequest(id) {
+  return {
+    type: ACCOUNT_UNPIN_REQUEST,
+    id,
+  };
+};
+
+export function unpinAccountSuccess(relationship) {
+  return {
+    type: ACCOUNT_UNPIN_SUCCESS,
+    relationship,
+  };
+};
+
+export function unpinAccountFail(error) {
+  return {
+    type: ACCOUNT_UNPIN_FAIL,
+    error,
+  };
+};
diff --git a/app/javascript/mastodon/actions/cards.js b/app/javascript/mastodon/actions/cards.js
deleted file mode 100644
index baf04833a2c97810d370cec64db2a9c374f4ab6e..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/actions/cards.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import api from '../api';
-
-export const STATUS_CARD_FETCH_REQUEST = 'STATUS_CARD_FETCH_REQUEST';
-export const STATUS_CARD_FETCH_SUCCESS = 'STATUS_CARD_FETCH_SUCCESS';
-export const STATUS_CARD_FETCH_FAIL    = 'STATUS_CARD_FETCH_FAIL';
-
-export function fetchStatusCard(id) {
-  return (dispatch, getState) => {
-    if (getState().getIn(['cards', id], null) !== null) {
-      return;
-    }
-
-    dispatch(fetchStatusCardRequest(id));
-
-    api(getState).get(`/api/v1/statuses/${id}/card`).then(response => {
-      if (!response.data.url) {
-        return;
-      }
-
-      dispatch(fetchStatusCardSuccess(id, response.data));
-    }).catch(error => {
-      dispatch(fetchStatusCardFail(id, error));
-    });
-  };
-};
-
-export function fetchStatusCardRequest(id) {
-  return {
-    type: STATUS_CARD_FETCH_REQUEST,
-    id,
-    skipLoading: true,
-  };
-};
-
-export function fetchStatusCardSuccess(id, card) {
-  return {
-    type: STATUS_CARD_FETCH_SUCCESS,
-    id,
-    card,
-    skipLoading: true,
-  };
-};
-
-export function fetchStatusCardFail(id, error) {
-  return {
-    type: STATUS_CARD_FETCH_FAIL,
-    id,
-    error,
-    skipLoading: true,
-    skipAlert: true,
-  };
-};
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index fe3e831d5fc621ee2c8bab495f23113792a4f76b..a4352faaba63746cd28cf22faab7c1c6799cb5ed 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -56,7 +56,7 @@ export function changeCompose(text) {
   };
 };
 
-export function replyCompose(status, router) {
+export function replyCompose(status, routerHistory) {
   return (dispatch, getState) => {
     dispatch({
       type: COMPOSE_REPLY,
@@ -64,7 +64,7 @@ export function replyCompose(status, router) {
     });
 
     if (!getState().getIn(['compose', 'mounted'])) {
-      router.push('/statuses/new');
+      routerHistory.push('/statuses/new');
     }
   };
 };
@@ -81,7 +81,7 @@ export function resetCompose() {
   };
 };
 
-export function mentionCompose(account, router) {
+export function mentionCompose(account, routerHistory) {
   return (dispatch, getState) => {
     dispatch({
       type: COMPOSE_MENTION,
@@ -89,12 +89,12 @@ export function mentionCompose(account, router) {
     });
 
     if (!getState().getIn(['compose', 'mounted'])) {
-      router.push('/statuses/new');
+      routerHistory.push('/statuses/new');
     }
   };
 };
 
-export function directCompose(account, router) {
+export function directCompose(account, routerHistory) {
   return (dispatch, getState) => {
     dispatch({
       type: COMPOSE_DIRECT,
@@ -102,12 +102,12 @@ export function directCompose(account, router) {
     });
 
     if (!getState().getIn(['compose', 'mounted'])) {
-      router.push('/statuses/new');
+      routerHistory.push('/statuses/new');
     }
   };
 };
 
-export function submitCompose() {
+export function submitCompose(routerHistory) {
   return function (dispatch, getState) {
     const status = getState().getIn(['compose', 'text'], '');
     const media  = getState().getIn(['compose', 'media_attachments']);
@@ -130,24 +130,31 @@ export function submitCompose() {
         'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
       },
     }).then(function (response) {
-      dispatch(insertIntoTagHistory(response.data.tags));
+      if (response.data.visibility === 'direct' && getState().getIn(['conversations', 'mounted']) <= 0 && routerHistory) {
+        routerHistory.push('/timelines/direct');
+      } else if (routerHistory && routerHistory.location.pathname === '/statuses/new' && window.history.state) {
+        routerHistory.goBack();
+      }
+
+      dispatch(insertIntoTagHistory(response.data.tags, status));
       dispatch(submitComposeSuccess({ ...response.data }));
 
-      // To make the app more responsive, immediately get the status into the columns
+      // To make the app more responsive, immediately push the status
+      // into the columns
 
-      const insertIfOnline = (timelineId) => {
+      const insertIfOnline = timelineId => {
         if (getState().getIn(['timelines', timelineId, 'items', 0]) !== null) {
           dispatch(updateTimeline(timelineId, { ...response.data }));
         }
       };
 
-      insertIfOnline('home');
+      if (response.data.visibility !== 'direct') {
+        insertIfOnline('home');
+      }
 
       if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
         insertIfOnline('community');
         insertIfOnline('public');
-      } else if (response.data.visibility === 'direct') {
-        insertIfOnline('direct');
       }
     }).catch(function (error) {
       dispatch(submitComposeFail(error));
@@ -390,13 +397,13 @@ export function hydrateCompose() {
   };
 }
 
-function insertIntoTagHistory(tags) {
+function insertIntoTagHistory(recognizedTags, text) {
   return (dispatch, getState) => {
     const state = getState();
     const oldHistory = state.getIn(['compose', 'tagHistory']);
     const me = state.getIn(['meta', 'me']);
-    const names = tags.map(({ name }) => name);
-    const intersectedOldHistory = oldHistory.filter(name => !names.includes(name));
+    const names = recognizedTags.map(tag => text.match(new RegExp(`#${tag.name}`, 'i'))[0].slice(1));
+    const intersectedOldHistory = oldHistory.filter(name => names.findIndex(newName => newName.toLowerCase() === name.toLowerCase()) === -1);
 
     names.push(...intersectedOldHistory.toJS());
 
diff --git a/app/javascript/mastodon/actions/conversations.js b/app/javascript/mastodon/actions/conversations.js
new file mode 100644
index 0000000000000000000000000000000000000000..3c2ea968060c8b32b097ce609ef5e04f670ff2e3
--- /dev/null
+++ b/app/javascript/mastodon/actions/conversations.js
@@ -0,0 +1,81 @@
+import api, { getLinks } from '../api';
+import {
+  importFetchedAccounts,
+  importFetchedStatuses,
+  importFetchedStatus,
+} from './importer';
+
+export const CONVERSATIONS_MOUNT   = 'CONVERSATIONS_MOUNT';
+export const CONVERSATIONS_UNMOUNT = 'CONVERSATIONS_UNMOUNT';
+
+export const CONVERSATIONS_FETCH_REQUEST = 'CONVERSATIONS_FETCH_REQUEST';
+export const CONVERSATIONS_FETCH_SUCCESS = 'CONVERSATIONS_FETCH_SUCCESS';
+export const CONVERSATIONS_FETCH_FAIL    = 'CONVERSATIONS_FETCH_FAIL';
+export const CONVERSATIONS_UPDATE        = 'CONVERSATIONS_UPDATE';
+
+export const CONVERSATIONS_READ = 'CONVERSATIONS_READ';
+
+export const mountConversations = () => ({
+  type: CONVERSATIONS_MOUNT,
+});
+
+export const unmountConversations = () => ({
+  type: CONVERSATIONS_UNMOUNT,
+});
+
+export const markConversationRead = conversationId => (dispatch, getState) => {
+  dispatch({
+    type: CONVERSATIONS_READ,
+    id: conversationId,
+  });
+
+  api(getState).post(`/api/v1/conversations/${conversationId}/read`);
+};
+
+export const expandConversations = ({ maxId } = {}) => (dispatch, getState) => {
+  dispatch(expandConversationsRequest());
+
+  const params = { max_id: maxId };
+
+  if (!maxId) {
+    params.since_id = getState().getIn(['conversations', 'items', 0, 'last_status']);
+  }
+
+  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));
+    })
+    .catch(err => dispatch(expandConversationsFail(err)));
+};
+
+export const expandConversationsRequest = () => ({
+  type: CONVERSATIONS_FETCH_REQUEST,
+});
+
+export const expandConversationsSuccess = (conversations, next) => ({
+  type: CONVERSATIONS_FETCH_SUCCESS,
+  conversations,
+  next,
+});
+
+export const expandConversationsFail = error => ({
+  type: CONVERSATIONS_FETCH_FAIL,
+  error,
+});
+
+export const updateConversations = conversation => dispatch => {
+  dispatch(importFetchedAccounts(conversation.accounts));
+
+  if (conversation.last_status) {
+    dispatch(importFetchedStatus(conversation.last_status));
+  }
+
+  dispatch({
+    type: CONVERSATIONS_UPDATE,
+    conversation,
+  });
+};
diff --git a/app/javascript/mastodon/actions/custom_emojis.js b/app/javascript/mastodon/actions/custom_emojis.js
index aa37bc42308f415ec903ae43f27388d3aacbf095..7b7d0091b56919d26d872f92e4d4502902140b7c 100644
--- a/app/javascript/mastodon/actions/custom_emojis.js
+++ b/app/javascript/mastodon/actions/custom_emojis.js
@@ -19,6 +19,7 @@ export function fetchCustomEmojis() {
 export function fetchCustomEmojisRequest() {
   return {
     type: CUSTOM_EMOJIS_FETCH_REQUEST,
+    skipLoading: true,
   };
 };
 
@@ -26,6 +27,7 @@ export function fetchCustomEmojisSuccess(custom_emojis) {
   return {
     type: CUSTOM_EMOJIS_FETCH_SUCCESS,
     custom_emojis,
+    skipLoading: true,
   };
 };
 
@@ -33,5 +35,6 @@ export function fetchCustomEmojisFail(error) {
   return {
     type: CUSTOM_EMOJIS_FETCH_FAIL,
     error,
+    skipLoading: true,
   };
 };
diff --git a/app/javascript/mastodon/actions/domain_blocks.js b/app/javascript/mastodon/actions/domain_blocks.js
index 47e2df76ba5cc914b35eb33259a2f14b2fe5a323..0445a5e10c6f72753935cdf2fa4fbed3f4650fd7 100644
--- a/app/javascript/mastodon/actions/domain_blocks.js
+++ b/app/javascript/mastodon/actions/domain_blocks.js
@@ -128,7 +128,7 @@ export function expandDomainBlocks() {
   return (dispatch, getState) => {
     const url = getState().getIn(['domain_lists', 'blocks', 'next']);
 
-    if (url === null) {
+    if (!url) {
       return;
     }
 
diff --git a/app/javascript/mastodon/actions/dropdown_menu.js b/app/javascript/mastodon/actions/dropdown_menu.js
index 217ba4e74a58a8140c1cb6c2ee53f19ce969ea18..14f2939c78db9cdfdd25612176a917f50876200d 100644
--- a/app/javascript/mastodon/actions/dropdown_menu.js
+++ b/app/javascript/mastodon/actions/dropdown_menu.js
@@ -1,8 +1,8 @@
 export const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN';
 export const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE';
 
-export function openDropdownMenu(id, placement) {
-  return { type: DROPDOWN_MENU_OPEN, id, placement };
+export function openDropdownMenu(id, placement, keyboard) {
+  return { type: DROPDOWN_MENU_OPEN, id, placement, keyboard };
 }
 
 export function closeDropdownMenu(id) {
diff --git a/app/javascript/mastodon/actions/favourites.js b/app/javascript/mastodon/actions/favourites.js
index 124cf8c44e36fc34840a00919c3f153d28d874dd..9448b1efe7eae93a64212d91cadde348cb7f086f 100644
--- a/app/javascript/mastodon/actions/favourites.js
+++ b/app/javascript/mastodon/actions/favourites.js
@@ -30,6 +30,7 @@ export function fetchFavouritedStatuses() {
 export function fetchFavouritedStatusesRequest() {
   return {
     type: FAVOURITED_STATUSES_FETCH_REQUEST,
+    skipLoading: true,
   };
 };
 
@@ -38,6 +39,7 @@ export function fetchFavouritedStatusesSuccess(statuses, next) {
     type: FAVOURITED_STATUSES_FETCH_SUCCESS,
     statuses,
     next,
+    skipLoading: true,
   };
 };
 
@@ -45,6 +47,7 @@ export function fetchFavouritedStatusesFail(error) {
   return {
     type: FAVOURITED_STATUSES_FETCH_FAIL,
     error,
+    skipLoading: true,
   };
 };
 
diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js
index 10a39e0504d6592d6c082c181e58899d744254e9..34a4150facb90c521a9e82f8142d20ebb2507a67 100644
--- a/app/javascript/mastodon/actions/importer/normalizer.js
+++ b/app/javascript/mastodon/actions/importer/normalizer.js
@@ -1,6 +1,7 @@
 import escapeTextContentForBrowser from 'escape-html';
 import emojify from '../../features/emoji/emoji';
 import { unescapeHTML } from '../../utils/html';
+import { expandSpoilers } from '../../initial_state';
 
 const domParser = new DOMParser();
 
@@ -13,7 +14,7 @@ export function normalizeAccount(account) {
   account = { ...account };
 
   const emojiMap = makeEmojiMap(account);
-  const displayName = account.display_name.length === 0 ? account.username : account.display_name;
+  const displayName = account.display_name.trim().length === 0 ? account.username : account.display_name;
 
   account.display_name_html = emojify(escapeTextContentForBrowser(displayName), emojiMap);
   account.note_emojified = emojify(account.note, emojiMap);
@@ -57,7 +58,7 @@ export function normalizeStatus(status, normalOldStatus) {
     normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent;
     normalStatus.contentHtml  = emojify(normalStatus.content, emojiMap);
     normalStatus.spoilerHtml  = emojify(escapeTextContentForBrowser(spoilerText), emojiMap);
-    normalStatus.hidden       = spoilerText.length > 0 || normalStatus.sensitive;
+    normalStatus.hidden       = expandSpoilers ? false : spoilerText.length > 0 || normalStatus.sensitive;
   }
 
   return normalStatus;
diff --git a/app/javascript/mastodon/actions/lists.js b/app/javascript/mastodon/actions/lists.js
index 12cb1715997ee4bafdbede05cc27345202810489..d736bacef4805770713765b24ca29cae1a5d7598 100644
--- a/app/javascript/mastodon/actions/lists.js
+++ b/app/javascript/mastodon/actions/lists.js
@@ -42,6 +42,13 @@ export const LIST_EDITOR_REMOVE_REQUEST = 'LIST_EDITOR_REMOVE_REQUEST';
 export const LIST_EDITOR_REMOVE_SUCCESS = 'LIST_EDITOR_REMOVE_SUCCESS';
 export const LIST_EDITOR_REMOVE_FAIL    = 'LIST_EDITOR_REMOVE_FAIL';
 
+export const LIST_ADDER_RESET = 'LIST_ADDER_RESET';
+export const LIST_ADDER_SETUP = 'LIST_ADDER_SETUP';
+
+export const LIST_ADDER_LISTS_FETCH_REQUEST = 'LIST_ADDER_LISTS_FETCH_REQUEST';
+export const LIST_ADDER_LISTS_FETCH_SUCCESS = 'LIST_ADDER_LISTS_FETCH_SUCCESS';
+export const LIST_ADDER_LISTS_FETCH_FAIL    = 'LIST_ADDER_LISTS_FETCH_FAIL';
+
 export const fetchList = id => (dispatch, getState) => {
   if (getState().getIn(['lists', id])) {
     return;
@@ -316,3 +323,50 @@ export const removeFromListFail = (listId, accountId, error) => ({
   accountId,
   error,
 });
+
+export const resetListAdder = () => ({
+  type: LIST_ADDER_RESET,
+});
+
+export const setupListAdder = accountId => (dispatch, getState) => {
+  dispatch({
+    type: LIST_ADDER_SETUP,
+    account: getState().getIn(['accounts', accountId]),
+  });
+  dispatch(fetchLists());
+  dispatch(fetchAccountLists(accountId));
+};
+
+export const fetchAccountLists = accountId => (dispatch, getState) => {
+  dispatch(fetchAccountListsRequest(accountId));
+
+  api(getState).get(`/api/v1/accounts/${accountId}/lists`)
+    .then(({ data }) => dispatch(fetchAccountListsSuccess(accountId, data)))
+    .catch(err => dispatch(fetchAccountListsFail(accountId, err)));
+};
+
+export const fetchAccountListsRequest = id => ({
+  type:LIST_ADDER_LISTS_FETCH_REQUEST,
+  id,
+});
+
+export const fetchAccountListsSuccess = (id, lists) => ({
+  type: LIST_ADDER_LISTS_FETCH_SUCCESS,
+  id,
+  lists,
+});
+
+export const fetchAccountListsFail = (id, err) => ({
+  type: LIST_ADDER_LISTS_FETCH_FAIL,
+  id,
+  err,
+});
+
+export const addToListAdder = listId => (dispatch, getState) => {
+  dispatch(addToList(listId, getState().getIn(['listAdder', 'accountId'])));
+};
+
+export const removeFromListAdder = listId => (dispatch, getState) => {
+  dispatch(removeFromList(listId, getState().getIn(['listAdder', 'accountId'])));
+};
+
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
index ad6430b823dcb595b021d0d308a9a0369f088902..4c145febc4fc1e9f2c32180588a923b6c4434d7f 100644
--- a/app/javascript/mastodon/actions/notifications.js
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -8,6 +8,7 @@ import {
   importFetchedStatuses,
 } from './importer';
 import { defineMessages } from 'react-intl';
+import { List as ImmutableList } from 'immutable';
 import { unescapeHTML } from '../utils/html';
 import { getFilters, regexFromFilters } from '../selectors';
 
@@ -18,6 +19,8 @@ export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST';
 export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS';
 export const NOTIFICATIONS_EXPAND_FAIL    = 'NOTIFICATIONS_EXPAND_FAIL';
 
+export const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET';
+
 export const NOTIFICATIONS_CLEAR      = 'NOTIFICATIONS_CLEAR';
 export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
 
@@ -88,11 +91,18 @@ 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']);
+  return allTypes.filterNot(item => item === filter).toJS();
+};
+
 const noOp = () => {};
 
 export function expandNotifications({ maxId } = {}, done = noOp) {
   return (dispatch, getState) => {
+    const activeFilter = getState().getIn(['settings', 'notifications', 'quickFilter', 'active']);
     const notifications = getState().get('notifications');
+    const isLoadingMore = !!maxId;
 
     if (notifications.get('isLoading')) {
       done();
@@ -101,14 +111,16 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
 
     const params = {
       max_id: maxId,
-      exclude_types: excludeTypesFromSettings(getState()),
+      exclude_types: activeFilter === 'all'
+        ? excludeTypesFromSettings(getState())
+        : excludeTypesFromFilter(activeFilter),
     };
 
     if (!maxId && notifications.get('items').size > 0) {
-      params.since_id = notifications.getIn(['items', 0]);
+      params.since_id = notifications.getIn(['items', 0, 'id']);
     }
 
-    dispatch(expandNotificationsRequest());
+    dispatch(expandNotificationsRequest(isLoadingMore));
 
     api(getState).get('/api/v1/notifications', { params }).then(response => {
       const next = getLinks(response).refs.find(link => link.rel === 'next');
@@ -116,34 +128,37 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
       dispatch(importFetchedAccounts(response.data.map(item => item.account)));
       dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
 
-      dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null));
+      dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore));
       fetchRelatedRelationships(dispatch, response.data);
       done();
     }).catch(error => {
-      dispatch(expandNotificationsFail(error));
+      dispatch(expandNotificationsFail(error, isLoadingMore));
       done();
     });
   };
 };
 
-export function expandNotificationsRequest() {
+export function expandNotificationsRequest(isLoadingMore) {
   return {
     type: NOTIFICATIONS_EXPAND_REQUEST,
+    skipLoading: !isLoadingMore,
   };
 };
 
-export function expandNotificationsSuccess(notifications, next) {
+export function expandNotificationsSuccess(notifications, next, isLoadingMore) {
   return {
     type: NOTIFICATIONS_EXPAND_SUCCESS,
     notifications,
     next,
+    skipLoading: !isLoadingMore,
   };
 };
 
-export function expandNotificationsFail(error) {
+export function expandNotificationsFail(error, isLoadingMore) {
   return {
     type: NOTIFICATIONS_EXPAND_FAIL,
     error,
+    skipLoading: !isLoadingMore,
   };
 };
 
@@ -163,3 +178,14 @@ export function scrollTopNotifications(top) {
     top,
   };
 };
+
+export function setFilter (filterType) {
+  return dispatch => {
+    dispatch({
+      type: NOTIFICATIONS_FILTER_SET,
+      path: ['notifications', 'quickFilter', 'active'],
+      value: filterType,
+    });
+    dispatch(expandNotifications());
+  };
+};
diff --git a/app/javascript/mastodon/actions/onboarding.js b/app/javascript/mastodon/actions/onboarding.js
index a161c50efed4858811d93ba44a92d600ac40fd8a..a1dd3a731eddc1ceda9a76d05ed5f7feff7bf74f 100644
--- a/app/javascript/mastodon/actions/onboarding.js
+++ b/app/javascript/mastodon/actions/onboarding.js
@@ -1,14 +1,8 @@
-import { openModal } from './modal';
 import { changeSetting, saveSettings } from './settings';
 
-export function showOnboardingOnce() {
-  return (dispatch, getState) => {
-    const alreadySeen = getState().getIn(['settings', 'onboarded']);
+export const INTRODUCTION_VERSION = 20181216044202;
 
-    if (!alreadySeen) {
-      dispatch(openModal('ONBOARDING'));
-      dispatch(changeSetting(['onboarded'], true));
-      dispatch(saveSettings());
-    }
-  };
+export const closeOnboarding = () => dispatch => {
+  dispatch(changeSetting(['introductionVersion'], INTRODUCTION_VERSION));
+  dispatch(saveSettings());
 };
diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js
index 3e1e5f2709685642d7f6849255ff2ed0e5d4b28f..e7c89b4ba8a4c49fc44e9ad0264ccd1d82cdd329 100644
--- a/app/javascript/mastodon/actions/statuses.js
+++ b/app/javascript/mastodon/actions/statuses.js
@@ -3,7 +3,6 @@ import openDB from '../storage/db';
 import { evictStatus } from '../storage/modifier';
 
 import { deleteFromTimelines } from './timelines';
-import { fetchStatusCard } from './cards';
 import { importFetchedStatus, importFetchedStatuses, importAccount, importStatus } from './importer';
 
 export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
@@ -86,7 +85,6 @@ export function fetchStatus(id) {
     const skipLoading = getState().getIn(['statuses', id], null) !== null;
 
     dispatch(fetchContext(id));
-    dispatch(fetchStatusCard(id));
 
     if (skipLoading) {
       return;
@@ -140,7 +138,7 @@ export function redraft(status) {
   };
 };
 
-export function deleteStatus(id, withRedraft = false) {
+export function deleteStatus(id, router, withRedraft = false) {
   return (dispatch, getState) => {
     const status = getState().getIn(['statuses', id]);
 
@@ -153,6 +151,10 @@ export function deleteStatus(id, withRedraft = false) {
 
       if (withRedraft) {
         dispatch(redraft(status));
+
+        if (!getState().getIn(['compose', 'mounted'])) {
+          router.push('/statuses/new');
+        }
       }
     }).catch(error => {
       dispatch(deleteStatusFail(id, error));
diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js
index 32fc67e67f76bdae9560f2cbfad01af0da03489b..cd319709d82b602d8008a67332fdfe724b306ff1 100644
--- a/app/javascript/mastodon/actions/streaming.js
+++ b/app/javascript/mastodon/actions/streaming.js
@@ -6,12 +6,13 @@ import {
   disconnectTimeline,
 } from './timelines';
 import { updateNotifications, expandNotifications } from './notifications';
+import { updateConversations } from './conversations';
 import { fetchFilters } from './filters';
 import { getLocale } from '../locales';
 
 const { messages } = getLocale();
 
-export function connectTimelineStream (timelineId, path, pollingRefresh = null) {
+export function connectTimelineStream (timelineId, path, pollingRefresh = null, accept = null) {
 
   return connectStream (path, pollingRefresh, (dispatch, getState) => {
     const locale = getState().getIn(['meta', 'locale']);
@@ -23,7 +24,7 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null)
       onReceive (data) {
         switch(data.event) {
         case 'update':
-          dispatch(updateTimeline(timelineId, JSON.parse(data.payload)));
+          dispatch(updateTimeline(timelineId, JSON.parse(data.payload), accept));
           break;
         case 'delete':
           dispatch(deleteFromTimelines(data.payload));
@@ -31,6 +32,9 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null)
         case 'notification':
           dispatch(updateNotifications(JSON.parse(data.payload), messages, locale));
           break;
+        case 'conversation':
+          dispatch(updateConversations(JSON.parse(data.payload)));
+          break;
         case 'filters_changed':
           dispatch(fetchFilters());
           break;
@@ -47,6 +51,6 @@ const refreshHomeTimelineAndNotification = (dispatch, done) => {
 export const connectUserStream      = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
 export const connectCommunityStream = ({ onlyMedia } = {}) => connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`);
 export const connectPublicStream    = ({ onlyMedia } = {}) => connectTimelineStream(`public${onlyMedia ? ':media' : ''}`, `public${onlyMedia ? ':media' : ''}`);
-export const connectHashtagStream   = tag => connectTimelineStream(`hashtag:${tag}`, `hashtag&tag=${tag}`);
+export const connectHashtagStream   = (id, tag, accept) => connectTimelineStream(`hashtag:${id}`, `hashtag&tag=${tag}`, null, accept);
 export const connectDirectStream    = () => connectTimelineStream('direct', 'direct');
 export const connectListStream      = id => connectTimelineStream(`list:${id}`, `list&list=${id}`);
diff --git a/app/javascript/mastodon/actions/suggestions.js b/app/javascript/mastodon/actions/suggestions.js
new file mode 100644
index 0000000000000000000000000000000000000000..b15bd916ba6a255718f9d20c658ff08ca5c83203
--- /dev/null
+++ b/app/javascript/mastodon/actions/suggestions.js
@@ -0,0 +1,52 @@
+import api from '../api';
+import { importFetchedAccounts } from './importer';
+
+export const SUGGESTIONS_FETCH_REQUEST = 'SUGGESTIONS_FETCH_REQUEST';
+export const SUGGESTIONS_FETCH_SUCCESS = 'SUGGESTIONS_FETCH_SUCCESS';
+export const SUGGESTIONS_FETCH_FAIL    = 'SUGGESTIONS_FETCH_FAIL';
+
+export const SUGGESTIONS_DISMISS = 'SUGGESTIONS_DISMISS';
+
+export function fetchSuggestions() {
+  return (dispatch, getState) => {
+    dispatch(fetchSuggestionsRequest());
+
+    api(getState).get('/api/v1/suggestions').then(response => {
+      dispatch(importFetchedAccounts(response.data));
+      dispatch(fetchSuggestionsSuccess(response.data));
+    }).catch(error => dispatch(fetchSuggestionsFail(error)));
+  };
+};
+
+export function fetchSuggestionsRequest() {
+  return {
+    type: SUGGESTIONS_FETCH_REQUEST,
+    skipLoading: true,
+  };
+};
+
+export function fetchSuggestionsSuccess(accounts) {
+  return {
+    type: SUGGESTIONS_FETCH_SUCCESS,
+    accounts,
+    skipLoading: true,
+  };
+};
+
+export function fetchSuggestionsFail(error) {
+  return {
+    type: SUGGESTIONS_FETCH_FAIL,
+    error,
+    skipLoading: true,
+    skipAlert: true,
+  };
+};
+
+export const dismissSuggestion = accountId => (dispatch, getState) => {
+  dispatch({
+    type: SUGGESTIONS_DISMISS,
+    id: accountId,
+  });
+
+  api(getState).delete(`/api/v1/suggestions/${accountId}`);
+};
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index 11a199db6ae0f9ce6cfbf185c031e56ebe5fa35d..6e7bd027cb782d1037b6b11be719fdf487fbf1fa 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -4,6 +4,7 @@ import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
 
 export const TIMELINE_UPDATE  = 'TIMELINE_UPDATE';
 export const TIMELINE_DELETE  = 'TIMELINE_DELETE';
+export const TIMELINE_CLEAR   = 'TIMELINE_CLEAR';
 
 export const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST';
 export const TIMELINE_EXPAND_SUCCESS = 'TIMELINE_EXPAND_SUCCESS';
@@ -13,9 +14,11 @@ export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
 
 export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
 
-export function updateTimeline(timeline, status) {
-  return (dispatch, getState) => {
-    const references = status.reblog ? getState().get('statuses').filter((item, itemId) => (itemId === status.reblog.id || item.get('reblog') === status.reblog.id)).map((_, itemId) => itemId) : [];
+export function updateTimeline(timeline, status, accept) {
+  return dispatch => {
+    if (typeof accept === 'function' && !accept(status)) {
+      return;
+    }
 
     dispatch(importFetchedStatus(status));
 
@@ -23,7 +26,6 @@ export function updateTimeline(timeline, status) {
       type: TIMELINE_UPDATE,
       timeline,
       status,
-      references,
     });
   };
 };
@@ -44,30 +46,45 @@ export function deleteFromTimelines(id) {
   };
 };
 
+export function clearTimeline(timeline) {
+  return (dispatch) => {
+    dispatch({ type: TIMELINE_CLEAR, timeline });
+  };
+};
+
 const noOp = () => {};
 
+const parseTags = (tags = {}, mode) => {
+  return (tags[mode] || []).map((tag) => {
+    return tag.value;
+  });
+};
+
 export function expandTimeline(timelineId, path, params = {}, done = noOp) {
   return (dispatch, getState) => {
     const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
+    const isLoadingMore = !!params.max_id;
 
     if (timeline.get('isLoading')) {
       done();
       return;
     }
 
-    if (!params.max_id && timeline.get('items', ImmutableList()).size > 0) {
+    if (!params.max_id && !params.pinned && timeline.get('items', ImmutableList()).size > 0) {
       params.since_id = timeline.getIn(['items', 0]);
     }
 
-    dispatch(expandTimelineRequest(timelineId));
+    const isLoadingRecent = !!params.since_id;
+
+    dispatch(expandTimelineRequest(timelineId, isLoadingMore));
 
     api(getState).get(path, { params }).then(response => {
       const next = getLinks(response).refs.find(link => link.rel === 'next');
       dispatch(importFetchedStatuses(response.data));
-      dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206));
+      dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore));
       done();
     }).catch(error => {
-      dispatch(expandTimelineFail(timelineId, error));
+      dispatch(expandTimelineFail(timelineId, error, isLoadingMore));
       done();
     });
   };
@@ -76,35 +93,45 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
 export const expandHomeTimeline            = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
 export const expandPublicTimeline          = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`public${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { max_id: maxId, only_media: !!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 expandDirectTimeline          = ({ maxId } = {}, done = noOp) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId }, 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 expandHashtagTimeline         = (hashtag, { maxId } = {}, done = noOp) => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`, { max_id: maxId }, done);
 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}`, {
+    max_id: maxId,
+    any:    parseTags(tags, 'any'),
+    all:    parseTags(tags, 'all'),
+    none:   parseTags(tags, 'none'),
+  }, done);
+};
 
-export function expandTimelineRequest(timeline) {
+export function expandTimelineRequest(timeline, isLoadingMore) {
   return {
     type: TIMELINE_EXPAND_REQUEST,
     timeline,
+    skipLoading: !isLoadingMore,
   };
 };
 
-export function expandTimelineSuccess(timeline, statuses, next, partial) {
+export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadingRecent, isLoadingMore) {
   return {
     type: TIMELINE_EXPAND_SUCCESS,
     timeline,
     statuses,
     next,
     partial,
+    isLoadingRecent,
+    skipLoading: !isLoadingMore,
   };
 };
 
-export function expandTimelineFail(timeline, error) {
+export function expandTimelineFail(timeline, error, isLoadingMore) {
   return {
     type: TIMELINE_EXPAND_FAIL,
     timeline,
     error,
+    skipLoading: !isLoadingMore,
   };
 };
 
diff --git a/app/javascript/mastodon/api.js b/app/javascript/mastodon/api.js
index 0be08d7fdd8fdd8dc4805376eddbe10f5ccd543d..4be3eadb022e5b0d512135b662566bc1e043cc3d 100644
--- a/app/javascript/mastodon/api.js
+++ b/app/javascript/mastodon/api.js
@@ -1,6 +1,6 @@
 import axios from 'axios';
+import LinkHeader from 'http-link-header';
 import ready from './ready';
-import LinkHeader from './link_header';
 
 export const getLinks = response => {
   const value = response.headers.link;
diff --git a/app/javascript/mastodon/common.js b/app/javascript/mastodon/common.js
new file mode 100644
index 0000000000000000000000000000000000000000..fba21316a77dc9c75dd7deea6e84b2b553d541dc
--- /dev/null
+++ b/app/javascript/mastodon/common.js
@@ -0,0 +1,12 @@
+import Rails from 'rails-ujs';
+
+export function start() {
+  require('font-awesome/css/font-awesome.css');
+  require.context('../images/', true);
+
+  try {
+    Rails.start();
+  } catch (e) {
+    // If called twice
+  }
+};
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..1c37278483c579471a67404c8e69f5e0e265ff18
--- /dev/null
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.js.snap
@@ -0,0 +1,27 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`<AutosuggestEmoji /> renders emoji with custom url 1`] = `
+<div
+  className="autosuggest-emoji"
+>
+  <img
+    alt="foobar"
+    className="emojione"
+    src="http://example.com/emoji.png"
+  />
+  :foobar:
+</div>
+`;
+
+exports[`<AutosuggestEmoji /> renders native emoji 1`] = `
+<div
+  className="autosuggest-emoji"
+>
+  <img
+    alt="💙"
+    className="emojione"
+    src="/emoji/1f499.svg"
+  />
+  :foobar:
+</div>
+`;
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/button-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/button-test.js.snap
index c3f018d90e507d86a89df3bbdc3405d373598bfa..5c04e09799f022cf9a30a19bc841dcc9731b0360 100644
--- a/app/javascript/mastodon/components/__tests__/__snapshots__/button-test.js.snap
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/button-test.js.snap
@@ -3,7 +3,6 @@
 exports[`<Button /> adds class "button-secondary" if props.secondary given 1`] = `
 <button
   className="button button-secondary"
-  disabled={undefined}
   onClick={[Function]}
   style={
     Object {
@@ -18,7 +17,6 @@ exports[`<Button /> adds class "button-secondary" if props.secondary given 1`] =
 exports[`<Button /> renders a button element 1`] = `
 <button
   className="button"
-  disabled={undefined}
   onClick={[Function]}
   style={
     Object {
@@ -48,7 +46,6 @@ exports[`<Button /> renders a disabled attribute if props.disabled given 1`] = `
 exports[`<Button /> renders class="button--block" if props.block given 1`] = `
 <button
   className="button button--block"
-  disabled={undefined}
   onClick={[Function]}
   style={
     Object {
@@ -63,7 +60,6 @@ exports[`<Button /> renders class="button--block" if props.block given 1`] = `
 exports[`<Button /> renders the children 1`] = `
 <button
   className="button"
-  disabled={undefined}
   onClick={[Function]}
   style={
     Object {
@@ -82,7 +78,6 @@ exports[`<Button /> renders the children 1`] = `
 exports[`<Button /> renders the given text 1`] = `
 <button
   className="button"
-  disabled={undefined}
   onClick={[Function]}
   style={
     Object {
@@ -99,7 +94,6 @@ exports[`<Button /> renders the given text 1`] = `
 exports[`<Button /> renders the props.text instead of children 1`] = `
 <button
   className="button"
-  disabled={undefined}
   onClick={[Function]}
   style={
     Object {
diff --git a/app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.js b/app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.js
new file mode 100644
index 0000000000000000000000000000000000000000..05616e444826cbaf4a8c65dfa30d3ef0f5e578a3
--- /dev/null
+++ b/app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.js
@@ -0,0 +1,29 @@
+import React from 'react';
+import renderer from 'react-test-renderer';
+import AutosuggestEmoji from '../autosuggest_emoji';
+
+describe('<AutosuggestEmoji />', () => {
+  it('renders native emoji', () => {
+    const emoji = {
+      native: '💙',
+      colons: ':foobar:',
+    };
+    const component = renderer.create(<AutosuggestEmoji emoji={emoji} />);
+    const tree      = component.toJSON();
+
+    expect(tree).toMatchSnapshot();
+  });
+
+  it('renders emoji with custom url', () => {
+    const emoji = {
+      custom: true,
+      imageUrl: 'http://example.com/emoji.png',
+      native: 'foobar',
+      colons: ':foobar:',
+    };
+    const component = renderer.create(<AutosuggestEmoji emoji={emoji} />);
+    const tree      = component.toJSON();
+
+    expect(tree).toMatchSnapshot();
+  });
+});
diff --git a/app/javascript/mastodon/components/account.js b/app/javascript/mastodon/components/account.js
index 8e6aa9d92b56a78a51aab12ea1a26a14e97a8170..206030c006bb34d48e2e9da2ec1dd1559c374f23 100644
--- a/app/javascript/mastodon/components/account.js
+++ b/app/javascript/mastodon/components/account.js
@@ -19,8 +19,8 @@ const messages = defineMessages({
   unmute_notifications: { id: 'account.unmute_notifications', defaultMessage: 'Unmute notifications from @{name}' },
 });
 
-@injectIntl
-export default class Account extends ImmutablePureComponent {
+export default @injectIntl
+class Account extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
@@ -30,6 +30,9 @@ export default class Account extends ImmutablePureComponent {
     onMuteNotifications: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
     hidden: PropTypes.bool,
+    actionIcon: PropTypes.string,
+    actionTitle: PropTypes.string,
+    onActionClick: PropTypes.func,
   };
 
   handleFollow = () => {
@@ -52,8 +55,12 @@ export default class Account extends ImmutablePureComponent {
     this.props.onMuteNotifications(this.props.account, false);
   }
 
+  handleAction = () => {
+    this.props.onActionClick(this.props.account);
+  }
+
   render () {
-    const { account, intl, hidden } = this.props;
+    const { account, intl, hidden, onActionClick, actionIcon, actionTitle } = this.props;
 
     if (!account) {
       return <div />;
@@ -61,16 +68,18 @@ export default class Account extends ImmutablePureComponent {
 
     if (hidden) {
       return (
-        <div>
+        <Fragment>
           {account.get('display_name')}
           {account.get('username')}
-        </div>
+        </Fragment>
       );
     }
 
     let buttons;
 
-    if (account.get('id') !== me && account.get('relationship', null) !== null) {
+    if (onActionClick && actionIcon) {
+      buttons = <IconButton icon={actionIcon} title={actionTitle} onClick={this.handleAction} />;
+    } else if (account.get('id') !== me && account.get('relationship', null) !== null) {
       const following = account.getIn(['relationship', 'following']);
       const requested = account.getIn(['relationship', 'requested']);
       const blocking  = account.getIn(['relationship', 'blocking']);
diff --git a/app/javascript/mastodon/components/avatar_composite.js b/app/javascript/mastodon/components/avatar_composite.js
new file mode 100644
index 0000000000000000000000000000000000000000..4a9a73c512e2cc0dc18649e331ea245c6bf913ca
--- /dev/null
+++ b/app/javascript/mastodon/components/avatar_composite.js
@@ -0,0 +1,96 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { autoPlayGif } from '../initial_state';
+
+export default class AvatarComposite extends React.PureComponent {
+
+  static propTypes = {
+    accounts: ImmutablePropTypes.list.isRequired,
+    animate: PropTypes.bool,
+    size: PropTypes.number.isRequired,
+  };
+
+  static defaultProps = {
+    animate: autoPlayGif,
+  };
+
+  renderItem (account, size, index) {
+    const { animate } = this.props;
+
+    let width  = 50;
+    let height = 100;
+    let top    = 'auto';
+    let left   = 'auto';
+    let bottom = 'auto';
+    let right  = 'auto';
+
+    if (size === 1) {
+      width = 100;
+    }
+
+    if (size === 4 || (size === 3 && index > 0)) {
+      height = 50;
+    }
+
+    if (size === 2) {
+      if (index === 0) {
+        right = '2px';
+      } else {
+        left = '2px';
+      }
+    } else if (size === 3) {
+      if (index === 0) {
+        right = '2px';
+      } else if (index > 0) {
+        left = '2px';
+      }
+
+      if (index === 1) {
+        bottom = '2px';
+      } else if (index > 1) {
+        top = '2px';
+      }
+    } else if (size === 4) {
+      if (index === 0 || index === 2) {
+        right = '2px';
+      }
+
+      if (index === 1 || index === 3) {
+        left = '2px';
+      }
+
+      if (index < 2) {
+        bottom = '2px';
+      } else {
+        top = '2px';
+      }
+    }
+
+    const style = {
+      left: left,
+      top: top,
+      right: right,
+      bottom: bottom,
+      width: `${width}%`,
+      height: `${height}%`,
+      backgroundSize: 'cover',
+      backgroundImage: `url(${account.get(animate ? 'avatar' : 'avatar_static')})`,
+    };
+
+    return (
+      <div key={account.get('id')} style={style} />
+    );
+  }
+
+  render() {
+    const { accounts, size } = this.props;
+
+    return (
+      <div className='account__avatar-composite' style={{ width: `${size}px`, height: `${size}px` }}>
+        {accounts.take(4).map((account, i) => this.renderItem(account, accounts.size, i))}
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/components/column.js b/app/javascript/mastodon/components/column.js
index e81236d265f2696b17822272def564dd96c83bf2..d453874636ed50261fabca67f0a61e2907111b06 100644
--- a/app/javascript/mastodon/components/column.js
+++ b/app/javascript/mastodon/components/column.js
@@ -7,6 +7,7 @@ export default class Column extends React.PureComponent {
 
   static propTypes = {
     children: PropTypes.node,
+    label: PropTypes.string,
   };
 
   scrollTop () {
@@ -40,10 +41,10 @@ export default class Column extends React.PureComponent {
   }
 
   render () {
-    const { children } = this.props;
+    const { label, children } = this.props;
 
     return (
-      <div role='region' className='column' ref={this.setRef}>
+      <div role='region' aria-label={label} className='column' ref={this.setRef}>
         {children}
       </div>
     );
diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js
index 56453aeacfea87f0a83467570b046c09cea938fb..f68e4155ebbc83df779f2e764d96d52d5059a1a5 100644
--- a/app/javascript/mastodon/components/column_header.js
+++ b/app/javascript/mastodon/components/column_header.js
@@ -10,8 +10,8 @@ const messages = defineMessages({
   moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right' },
 });
 
-@injectIntl
-export default class ColumnHeader extends React.PureComponent {
+export default @injectIntl
+class ColumnHeader extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -37,6 +37,14 @@ export default class ColumnHeader extends React.PureComponent {
     animating: false,
   };
 
+  historyBack = () => {
+    if (window.history && window.history.length === 1) {
+      this.context.router.history.push('/');
+    } else {
+      this.context.router.history.goBack();
+    }
+  }
+
   handleToggleClick = (e) => {
     e.stopPropagation();
     this.setState({ collapsed: !this.state.collapsed, animating: true });
@@ -55,16 +63,22 @@ export default class ColumnHeader extends React.PureComponent {
   }
 
   handleBackClick = () => {
-    if (window.history && window.history.length === 1) this.context.router.history.push('/');
-    else this.context.router.history.goBack();
+    this.historyBack();
   }
 
   handleTransitionEnd = () => {
     this.setState({ animating: false });
   }
 
+  handlePin = () => {
+    if (!this.props.pinned) {
+      this.historyBack();
+    }
+    this.props.onPin();
+  }
+
   render () {
-    const { title, icon, active, children, pinned, onPin, multiColumn, extraButton, showBackButton, intl: { formatMessage } } = this.props;
+    const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage } } = this.props;
     const { collapsed, animating } = this.state;
 
     const wrapperClassName = classNames('column-header__wrapper', {
@@ -95,7 +109,7 @@ export default class ColumnHeader extends React.PureComponent {
     }
 
     if (multiColumn && pinned) {
-      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={onPin}><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}><i className='fa fa fa-times' /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>;
 
       moveButtons = (
         <div key='move-buttons' className='column-header__setting-arrows'>
@@ -104,7 +118,7 @@ export default class ColumnHeader extends React.PureComponent {
         </div>
       );
     } else if (multiColumn) {
-      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={onPin}><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}><i className='fa fa fa-plus' /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
     }
 
     if (!pinned && (multiColumn || showBackButton)) {
diff --git a/app/javascript/mastodon/components/display_name.js b/app/javascript/mastodon/components/display_name.js
index a1c56ae359b63f50f81f73ae2ae0b7799b9fecc3..acddf77c54361806b5c695c1c2540940daf245a3 100644
--- a/app/javascript/mastodon/components/display_name.js
+++ b/app/javascript/mastodon/components/display_name.js
@@ -1,18 +1,36 @@
 import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import PropTypes from 'prop-types';
 
 export default class DisplayName extends React.PureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
+    others: ImmutablePropTypes.list,
+    localDomain: PropTypes.string,
   };
 
   render () {
-    const displayNameHtml = { __html: this.props.account.get('display_name_html') };
+    const { account, others, localDomain } = this.props;
+    const displayNameHtml = { __html: account.get('display_name_html') };
+
+    let suffix;
+
+    if (others && others.size > 1) {
+      suffix = `+${others.size}`;
+    } else {
+      let acct = account.get('acct');
+
+      if (acct.indexOf('@') === -1 && localDomain) {
+        acct = `${acct}@${localDomain}`;
+      }
+
+      suffix = <span className='display-name__account'>@{acct}</span>;
+    }
 
     return (
       <span className='display-name'>
-        <bdi><strong className='display-name__html' dangerouslySetInnerHTML={displayNameHtml} /></bdi> <span className='display-name__account'>@{this.props.account.get('acct')}</span>
+        <bdi><strong className='display-name__html' dangerouslySetInnerHTML={displayNameHtml} /></bdi> {suffix}
       </span>
     );
   }
diff --git a/app/javascript/mastodon/components/domain.js b/app/javascript/mastodon/components/domain.js
index f657cb8d2d34434603982c22b0d447d469497506..24f80e7888a61ca38b9f3723bd530a85b4061312 100644
--- a/app/javascript/mastodon/components/domain.js
+++ b/app/javascript/mastodon/components/domain.js
@@ -8,8 +8,8 @@ const messages = defineMessages({
   unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
 });
 
-@injectIntl
-export default class Account extends ImmutablePureComponent {
+export default @injectIntl
+class Account extends ImmutablePureComponent {
 
   static propTypes = {
     domain: PropTypes.string,
diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js
index 0a6e7c62721fda680e6f04ec6311e14cc3f0ef4e..91b65a02fb60da2e1c9f896bc01bd030504f2197 100644
--- a/app/javascript/mastodon/components/dropdown_menu.js
+++ b/app/javascript/mastodon/components/dropdown_menu.js
@@ -23,6 +23,7 @@ class DropdownMenu extends React.PureComponent {
     placement: PropTypes.string,
     arrowOffsetLeft: PropTypes.string,
     arrowOffsetTop: PropTypes.string,
+    openedViaKeyboard: PropTypes.bool,
   };
 
   static defaultProps = {
@@ -42,13 +43,15 @@ class DropdownMenu extends React.PureComponent {
 
   componentDidMount () {
     document.addEventListener('click', this.handleDocumentClick, false);
+    document.addEventListener('keydown', this.handleKeyDown, false);
     document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
-    if (this.focusedItem) this.focusedItem.focus();
+    if (this.focusedItem && this.props.openedViaKeyboard) this.focusedItem.focus();
     this.setState({ mounted: true });
   }
 
   componentWillUnmount () {
     document.removeEventListener('click', this.handleDocumentClick, false);
+    document.removeEventListener('keydown', this.handleKeyDown, false);
     document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
   }
 
@@ -62,13 +65,10 @@ class DropdownMenu extends React.PureComponent {
 
   handleKeyDown = e => {
     const items = Array.from(this.node.getElementsByTagName('a'));
-    const index = items.indexOf(e.currentTarget);
+    const index = items.indexOf(document.activeElement);
     let element;
 
     switch(e.key) {
-    case 'Enter':
-      this.handleClick(e);
-      break;
     case 'ArrowDown':
       element = items[index+1];
       if (element) {
@@ -96,6 +96,12 @@ class DropdownMenu extends React.PureComponent {
     }
   }
 
+  handleItemKeyDown = e => {
+    if (e.key === 'Enter') {
+      this.handleClick(e);
+    }
+  }
+
   handleClick = e => {
     const i = Number(e.currentTarget.getAttribute('data-index'));
     const { action, to } = this.props.items[i];
@@ -120,7 +126,7 @@ class DropdownMenu extends React.PureComponent {
 
     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.handleKeyDown} data-index={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}>
           {text}
         </a>
       </li>
@@ -137,7 +143,7 @@ class DropdownMenu 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='dropdown-menu' style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}>
+          <div className={`dropdown-menu ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}>
             <div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} />
 
             <ul>
@@ -170,6 +176,7 @@ export default class Dropdown extends React.PureComponent {
     onClose: PropTypes.func.isRequired,
     dropdownPlacement: PropTypes.string,
     openDropdownId: PropTypes.number,
+    openedViaKeyboard: PropTypes.bool,
   };
 
   static defaultProps = {
@@ -180,14 +187,14 @@ export default class Dropdown extends React.PureComponent {
     id: id++,
   };
 
-  handleClick = ({ target }) => {
+  handleClick = ({ target, type }) => {
     if (this.state.id === this.props.openDropdownId) {
       this.handleClose();
     } else {
       const { top } = target.getBoundingClientRect();
       const placement = top * 2 < innerHeight ? 'bottom' : 'top';
 
-      this.props.onOpen(this.state.id, this.handleItemClick, placement);
+      this.props.onOpen(this.state.id, this.handleItemClick, placement, type !== 'click');
     }
   }
 
@@ -197,6 +204,11 @@ export default class Dropdown extends React.PureComponent {
 
   handleKeyDown = e => {
     switch(e.key) {
+    case ' ':
+    case 'Enter':
+      this.handleClick(e);
+      e.preventDefault();
+      break;
     case 'Escape':
       this.handleClose();
       break;
@@ -226,8 +238,14 @@ export default class Dropdown extends React.PureComponent {
     return this.target;
   }
 
+  componentWillUnmount = () => {
+    if (this.state.id === this.props.openDropdownId) {
+      this.handleClose();
+    }
+  }
+
   render () {
-    const { icon, items, size, title, disabled, dropdownPlacement, openDropdownId } = this.props;
+    const { icon, items, size, title, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard } = this.props;
     const open = this.state.id === openDropdownId;
 
     return (
@@ -243,7 +261,7 @@ export default class Dropdown extends React.PureComponent {
         />
 
         <Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
-          <DropdownMenu items={items} onClose={this.handleClose} />
+          <DropdownMenu items={items} onClose={this.handleClose} openedViaKeyboard={openedViaKeyboard} />
         </Overlay>
       </div>
     );
diff --git a/app/javascript/mastodon/components/extended_video_player.js b/app/javascript/mastodon/components/extended_video_player.js
index 9e2f6835a8bdf9c2827ccf965ab9081d98ae0ee5..009c0d559ad67e60e0789c03aacf1be84ad69a2a 100644
--- a/app/javascript/mastodon/components/extended_video_player.js
+++ b/app/javascript/mastodon/components/extended_video_player.js
@@ -50,6 +50,7 @@ export default class ExtendedVideoPlayer extends React.PureComponent {
           role='button'
           tabIndex='0'
           aria-label={alt}
+          title={alt}
           muted={muted}
           controls={controls}
           loop={!controls}
diff --git a/app/javascript/mastodon/components/hashtag.js b/app/javascript/mastodon/components/hashtag.js
index a407df31e352430b23183a728836b7ac2e477a11..f091d7893e6631e0f6c12983f8a139854d78051a 100644
--- a/app/javascript/mastodon/components/hashtag.js
+++ b/app/javascript/mastodon/components/hashtag.js
@@ -1,16 +1,16 @@
 import React from 'react';
 import { Sparklines, SparklinesCurve } from 'react-sparklines';
-import { Link } from 'react-router-dom';
 import { FormattedMessage } from 'react-intl';
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import Permalink from './permalink';
 import { shortNumberFormat } from '../utils/numbers';
 
 const Hashtag = ({ hashtag }) => (
   <div className='trends__item'>
     <div className='trends__item__name'>
-      <Link to={`/timelines/tag/${hashtag.get('name')}`}>
+      <Permalink href={hashtag.get('url')} to={`/timelines/tag/${hashtag.get('name')}`}>
         #<span>{hashtag.get('name')}</span>
-      </Link>
+      </Permalink>
 
       <FormattedMessage id='trends.count_by_accounts' defaultMessage='{count} {rawCount, plural, one {person} other {people}} talking' values={{ rawCount: hashtag.getIn(['history', 0, 'accounts']), count: <strong>{shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']))}</strong> }} />
     </div>
diff --git a/app/javascript/mastodon/components/intersection_observer_article.js b/app/javascript/mastodon/components/intersection_observer_article.js
index e2ce9ec9651b819346f232a4eb34d17455ffd355..de2203a4bc4c6975bf5f29d4ad5a8ecb118c3e4a 100644
--- a/app/javascript/mastodon/components/intersection_observer_article.js
+++ b/app/javascript/mastodon/components/intersection_observer_article.js
@@ -109,7 +109,7 @@ export default class IntersectionObserverArticle extends React.Component {
       return (
         <article
           ref={this.handleRef}
-          aria-posinset={index}
+          aria-posinset={index + 1}
           aria-setsize={listLength}
           style={{ height: `${this.height || cachedHeight}px`, opacity: 0, overflow: 'hidden' }}
           data-id={id}
@@ -121,7 +121,7 @@ export default class IntersectionObserverArticle extends React.Component {
     }
 
     return (
-      <article ref={this.handleRef} aria-posinset={index} aria-setsize={listLength} data-id={id} tabIndex='0'>
+      <article ref={this.handleRef} aria-posinset={index + 1} aria-setsize={listLength} data-id={id} tabIndex='0'>
         {children && React.cloneElement(children, { hidden: false })}
       </article>
     );
diff --git a/app/javascript/mastodon/components/load_gap.js b/app/javascript/mastodon/components/load_gap.js
index 012303ae1ebe1b5a8a207e1c2460bc8d7403d5a4..ed4d445d0d3edc398d4563fa879818ddad35231b 100644
--- a/app/javascript/mastodon/components/load_gap.js
+++ b/app/javascript/mastodon/components/load_gap.js
@@ -6,8 +6,8 @@ const messages = defineMessages({
   load_more: { id: 'status.load_more', defaultMessage: 'Load more' },
 });
 
-@injectIntl
-export default class LoadGap extends React.PureComponent {
+export default @injectIntl
+class LoadGap extends React.PureComponent {
 
   static propTypes = {
     disabled: PropTypes.bool,
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index 1d351279f2be3fa79dac58ea5ea52f34987b0cd3..c507920d0ee34aeeebdb0079c76990279dae234c 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -6,7 +6,7 @@ import IconButton from './icon_button';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { isIOS } from '../is_mobile';
 import classNames from 'classnames';
-import { autoPlayGif, displaySensitiveMedia } from '../initial_state';
+import { autoPlayGif, displayMedia } from '../initial_state';
 
 const messages = defineMessages({
   toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' },
@@ -50,7 +50,11 @@ class Item extends React.PureComponent {
   handleClick = (e) => {
     const { index, onClick } = this.props;
 
-    if (e.button === 0) {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      if (this.hoverToPlay()) {
+        e.target.pause();
+        e.target.currentTime = 0;
+      }
       e.preventDefault();
       onClick(index);
     }
@@ -154,6 +158,7 @@ class Item extends React.PureComponent {
           <video
             className='media-gallery__item-gifv-thumbnail'
             aria-label={attachment.get('description')}
+            title={attachment.get('description')}
             role='application'
             src={attachment.get('url')}
             onClick={this.handleClick}
@@ -178,8 +183,8 @@ class Item extends React.PureComponent {
 
 }
 
-@injectIntl
-export default class MediaGallery extends React.PureComponent {
+export default @injectIntl
+class MediaGallery extends React.PureComponent {
 
   static propTypes = {
     sensitive: PropTypes.bool,
@@ -196,7 +201,7 @@ export default class MediaGallery extends React.PureComponent {
   };
 
   state = {
-    visible: !this.props.sensitive || displaySensitiveMedia,
+    visible: displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all',
   };
 
   componentWillReceiveProps (nextProps) {
diff --git a/app/javascript/mastodon/components/modal_root.js b/app/javascript/mastodon/components/modal_root.js
index 114f74937d281cb5e8c0d2b01dcea5127a1aa017..ef1156571f149fe38235fe9711b1cf7776b413a4 100644
--- a/app/javascript/mastodon/components/modal_root.js
+++ b/app/javascript/mastodon/components/modal_root.js
@@ -33,13 +33,15 @@ export default class ModalRoot extends React.PureComponent {
     } else if (!nextProps.children) {
       this.setState({ revealed: false });
     }
+    if (!nextProps.children && !!this.props.children) {
+      this.activeElement.focus();
+      this.activeElement = null;
+    }
   }
 
   componentDidUpdate (prevProps) {
     if (!this.props.children && !!prevProps.children) {
       this.getSiblings().forEach(sibling => sibling.removeAttribute('inert'));
-      this.activeElement.focus();
-      this.activeElement = null;
     }
     if (this.props.children) {
       requestAnimationFrame(() => {
diff --git a/app/javascript/mastodon/components/relative_timestamp.js b/app/javascript/mastodon/components/relative_timestamp.js
index 3c8db709269cde2142cb3f314da7aafe612e6aaf..57d99dd199d75db223ac4acdfacd6cf6fa4cf8d1 100644
--- a/app/javascript/mastodon/components/relative_timestamp.js
+++ b/app/javascript/mastodon/components/relative_timestamp.js
@@ -60,8 +60,34 @@ const getUnitDelay = units => {
   }
 };
 
-@injectIntl
-export default class RelativeTimestamp extends React.Component {
+export const timeAgoString = (intl, date, now, year) => {
+  const delta = now - date.getTime();
+
+  let relativeTime;
+
+  if (delta < 10 * SECOND) {
+    relativeTime = intl.formatMessage(messages.just_now);
+  } else if (delta < 7 * DAY) {
+    if (delta < MINUTE) {
+      relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) });
+    } else if (delta < HOUR) {
+      relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) });
+    } else if (delta < DAY) {
+      relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) });
+    } else {
+      relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) });
+    }
+  } else if (date.getFullYear() === year) {
+    relativeTime = intl.formatDate(date, shortDateFormatOptions);
+  } else {
+    relativeTime = intl.formatDate(date, { ...shortDateFormatOptions, year: 'numeric' });
+  }
+
+  return relativeTime;
+};
+
+export default @injectIntl
+class RelativeTimestamp extends React.Component {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
@@ -121,28 +147,8 @@ export default class RelativeTimestamp extends React.Component {
   render () {
     const { timestamp, intl, year } = this.props;
 
-    const date  = new Date(timestamp);
-    const delta = this.state.now - date.getTime();
-
-    let relativeTime;
-
-    if (delta < 10 * SECOND) {
-      relativeTime = intl.formatMessage(messages.just_now);
-    } else if (delta < 7 * DAY) {
-      if (delta < MINUTE) {
-        relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) });
-      } else if (delta < HOUR) {
-        relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) });
-      } else if (delta < DAY) {
-        relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) });
-      } else {
-        relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) });
-      }
-    } else if (date.getFullYear() === year) {
-      relativeTime = intl.formatDate(date, shortDateFormatOptions);
-    } else {
-      relativeTime = intl.formatDate(date, { ...shortDateFormatOptions, year: 'numeric' });
-    }
+    const date         = new Date(timestamp);
+    const relativeTime = 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 4b433f32c38d953ced4786b2d601084d20dfefd0..fec06e26373357cd6002176c4860af2a693a69fc 100644
--- a/app/javascript/mastodon/components/scrollable_list.js
+++ b/app/javascript/mastodon/components/scrollable_list.js
@@ -8,6 +8,9 @@ import { throttle } from 'lodash';
 import { List as ImmutableList } from 'immutable';
 import classNames from 'classnames';
 import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../features/ui/util/fullscreen';
+import LoadingIndicator from './loading_indicator';
+
+const MOUSE_IDLE_DELAY = 300;
 
 export default class ScrollableList extends PureComponent {
 
@@ -23,6 +26,7 @@ export default class ScrollableList extends PureComponent {
     trackScroll: PropTypes.bool,
     shouldUpdateScroll: PropTypes.func,
     isLoading: PropTypes.bool,
+    showLoading: PropTypes.bool,
     hasMore: PropTypes.bool,
     prepend: PropTypes.node,
     alwaysPrepend: PropTypes.bool,
@@ -45,7 +49,7 @@ export default class ScrollableList extends PureComponent {
       const { scrollTop, scrollHeight, clientHeight } = this.node;
       const offset = scrollHeight - scrollTop - clientHeight;
 
-      if (400 > offset && this.props.onLoadMore && !this.props.isLoading) {
+      if (400 > offset && this.props.onLoadMore && this.props.hasMore && !this.props.isLoading) {
         this.props.onLoadMore();
       }
 
@@ -54,14 +58,72 @@ export default class ScrollableList extends PureComponent {
       } else if (this.props.onScroll) {
         this.props.onScroll();
       }
+
+      if (!this.lastScrollWasSynthetic) {
+        // If the last scroll wasn't caused by setScrollTop(), assume it was
+        // intentional and cancel any pending scroll reset on mouse idle
+        this.scrollToTopOnMouseIdle = false;
+      }
+      this.lastScrollWasSynthetic = false;
+    }
+  }, 150, {
+    trailing: true,
+  });
+
+  mouseIdleTimer = null;
+  mouseMovedRecently = false;
+  lastScrollWasSynthetic = false;
+  scrollToTopOnMouseIdle = false;
+
+  setScrollTop = newScrollTop => {
+    if (this.node.scrollTop !== newScrollTop) {
+      this.lastScrollWasSynthetic = true;
+      this.node.scrollTop = newScrollTop;
     }
+  };
+
+  clearMouseIdleTimer = () => {
+    if (this.mouseIdleTimer === null) {
+      return;
+    }
+
+    clearTimeout(this.mouseIdleTimer);
+    this.mouseIdleTimer = null;
+  };
+
+  handleMouseMove = throttle(() => {
+    // As long as the mouse keeps moving, clear and restart the idle timer.
+    this.clearMouseIdleTimer();
+    this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY);
+
+    if (!this.mouseMovedRecently && this.node.scrollTop === 0) {
+      // Only set if we just started moving and are scrolled to the top.
+      this.scrollToTopOnMouseIdle = true;
+    }
+
+    // Save setting this flag for last, so we can do the comparison above.
+    this.mouseMovedRecently = true;
+  }, MOUSE_IDLE_DELAY / 2);
+
+  handleWheel = throttle(() => {
+    this.scrollToTopOnMouseIdle = false;
   }, 150, {
     trailing: true,
   });
 
+  handleMouseIdle = () => {
+    if (this.scrollToTopOnMouseIdle) {
+      this.setScrollTop(0);
+    }
+
+    this.mouseMovedRecently = false;
+    this.scrollToTopOnMouseIdle = false;
+  }
+
   componentDidMount () {
     this.attachScrollListener();
     this.attachIntersectionObserver();
+
     attachFullscreenListener(this.onFullScreenChange);
 
     // Handle initial scroll posiiton
@@ -72,7 +134,8 @@ export default class ScrollableList extends PureComponent {
     const someItemInserted = React.Children.count(prevProps.children) > 0 &&
       React.Children.count(prevProps.children) < React.Children.count(this.props.children) &&
       this.getFirstChildKey(prevProps) !== this.getFirstChildKey(this.props);
-    if (someItemInserted && this.node.scrollTop > 0) {
+
+    if (someItemInserted && (this.node.scrollTop > 0 || this.mouseMovedRecently)) {
       return this.node.scrollHeight - this.node.scrollTop;
     } else {
       return null;
@@ -83,15 +146,12 @@ export default class ScrollableList extends PureComponent {
     // Reset the scroll position when a new child comes in in order not to
     // jerk the scrollbar around if you're already scrolled down the page.
     if (snapshot !== null) {
-      const newScrollTop = this.node.scrollHeight - snapshot;
-
-      if (this.node.scrollTop !== newScrollTop) {
-        this.node.scrollTop = newScrollTop;
-      }
+      this.setScrollTop(this.node.scrollHeight - snapshot);
     }
   }
 
   componentWillUnmount () {
+    this.clearMouseIdleTimer();
     this.detachScrollListener();
     this.detachIntersectionObserver();
     detachFullscreenListener(this.onFullScreenChange);
@@ -114,20 +174,24 @@ export default class ScrollableList extends PureComponent {
 
   attachScrollListener () {
     this.node.addEventListener('scroll', this.handleScroll);
+    this.node.addEventListener('wheel', this.handleWheel);
   }
 
   detachScrollListener () {
     this.node.removeEventListener('scroll', this.handleScroll);
+    this.node.removeEventListener('wheel', this.handleWheel);
   }
 
   getFirstChildKey (props) {
     const { children } = props;
-    let firstChild = children;
+    let firstChild     = children;
+
     if (children instanceof ImmutableList) {
       firstChild = children.get(0);
     } else if (Array.isArray(children)) {
       firstChild = children[0];
     }
+
     return firstChild && firstChild.key;
   }
 
@@ -135,22 +199,34 @@ export default class ScrollableList extends PureComponent {
     this.node = c;
   }
 
-  handleLoadMore = (e) => {
+  handleLoadMore = e => {
     e.preventDefault();
     this.props.onLoadMore();
   }
 
   render () {
-    const { children, scrollKey, trackScroll, shouldUpdateScroll, isLoading, hasMore, prepend, alwaysPrepend, emptyMessage, onLoadMore } = this.props;
+    const { children, scrollKey, trackScroll, shouldUpdateScroll, showLoading, isLoading, hasMore, prepend, alwaysPrepend, emptyMessage, onLoadMore } = this.props;
     const { fullscreen } = this.state;
     const childrenCount = React.Children.count(children);
 
-    const loadMore     = (hasMore && childrenCount > 0 && onLoadMore) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
+    const loadMore     = (hasMore && onLoadMore) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
     let scrollableArea = null;
 
-    if (isLoading || childrenCount > 0 || !emptyMessage) {
+    if (showLoading) {
+      scrollableArea = (
+        <div className='scrollable scrollable--flex' ref={this.setRef}>
+          <div role='feed' className='item-list'>
+            {prepend}
+          </div>
+
+          <div className='scrollable__append'>
+            <LoadingIndicator />
+          </div>
+        </div>
+      );
+    } else if (isLoading || childrenCount > 0 || hasMore || !emptyMessage) {
       scrollableArea = (
-        <div className={classNames('scrollable', { fullscreen })} ref={this.setRef}>
+        <div className={classNames('scrollable', { fullscreen })} ref={this.setRef} onMouseMove={this.handleMouseMove}>
           <div role='feed' className='item-list'>
             {prepend}
 
@@ -173,10 +249,10 @@ export default class ScrollableList extends PureComponent {
       );
     } else {
       scrollableArea = (
-        <div style={{ flex: '1 1 auto', display: 'flex', flexDirection: 'column' }}>
+        <div className={classNames('scrollable scrollable--flex', { fullscreen })} ref={this.setRef}>
           {alwaysPrepend && prepend}
 
-          <div className='empty-column-indicator' ref={this.setRef}>
+          <div className='empty-column-indicator'>
             {emptyMessage}
           </div>
         </div>
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 922b609eceae5762d4bd0d847c47ec0472dfef2f..20d838500967f3c2d2e75c117ab2b46141b5510b 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -3,12 +3,14 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import Avatar from './avatar';
 import AvatarOverlay from './avatar_overlay';
+import AvatarComposite from './avatar_composite';
 import RelativeTimestamp from './relative_timestamp';
 import DisplayName from './display_name';
 import StatusContent from './status_content';
 import StatusActionBar from './status_action_bar';
 import AttachmentList from './attachment_list';
-import { FormattedMessage } from 'react-intl';
+import Card from '../features/status/components/card';
+import { injectIntl, FormattedMessage } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { MediaGallery, Video } from '../features/ui/util/async-components';
 import { HotKeys } from 'react-hotkeys';
@@ -18,7 +20,25 @@ import classNames from 'classnames';
 // to use the progress bar to show download progress
 import Bundle from '../features/ui/components/bundle';
 
-export default class Status extends ImmutablePureComponent {
+export const textForScreenReader = (intl, status, rebloggedByText = false) => {
+  const displayName = status.getIn(['account', 'display_name']);
+
+  const values = [
+    displayName.length === 0 ? status.getIn(['account', 'acct']).split('@')[0] : displayName,
+    status.get('spoiler_text') && status.get('hidden') ? status.get('spoiler_text') : status.get('search_index').slice(status.get('spoiler_text').length),
+    intl.formatDate(status.get('created_at'), { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }),
+    status.getIn(['account', 'acct']),
+  ];
+
+  if (rebloggedByText) {
+    values.push(rebloggedByText);
+  }
+
+  return values.join(', ');
+};
+
+export default @injectIntl
+class Status extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -27,6 +47,8 @@ export default class Status extends ImmutablePureComponent {
   static propTypes = {
     status: ImmutablePropTypes.map,
     account: ImmutablePropTypes.map,
+    otherAccounts: ImmutablePropTypes.list,
+    onClick: PropTypes.func,
     onReply: PropTypes.func,
     onFavourite: PropTypes.func,
     onReblog: PropTypes.func,
@@ -42,8 +64,10 @@ export default class Status extends ImmutablePureComponent {
     onToggleHidden: PropTypes.func,
     muted: PropTypes.bool,
     hidden: PropTypes.bool,
+    unread: PropTypes.bool,
     onMoveUp: PropTypes.func,
     onMoveDown: PropTypes.func,
+    showThread: PropTypes.bool,
   };
 
   // Avoid checking props that are functions (and whose equality will always
@@ -53,9 +77,14 @@ export default class Status extends ImmutablePureComponent {
     'account',
     'muted',
     'hidden',
-  ]
+  ];
 
   handleClick = () => {
+    if (this.props.onClick) {
+      this.props.onClick();
+      return;
+    }
+
     if (!this.context.router) {
       return;
     }
@@ -65,7 +94,7 @@ export default class Status extends ImmutablePureComponent {
   }
 
   handleAccountClick = (e) => {
-    if (this.context.router && e.button === 0) {
+    if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
       const id = e.currentTarget.getAttribute('data-id');
       e.preventDefault();
       this.context.router.history.push(`/accounts/${id}`);
@@ -138,9 +167,9 @@ export default class Status extends ImmutablePureComponent {
 
   render () {
     let media = null;
-    let statusAvatar, prepend;
+    let statusAvatar, prepend, rebloggedByText;
 
-    const { hidden, featured } = this.props;
+    const { intl, hidden, featured, otherAccounts, unread, showThread } = this.props;
 
     let { status, account, ...other } = this.props;
 
@@ -189,6 +218,8 @@ export default class Status extends ImmutablePureComponent {
         </div>
       );
 
+      rebloggedByText = intl.formatMessage({ id: 'status.reblogged_by', defaultMessage: '{name} boosted' }, { name: status.getIn(['account', 'acct']) });
+
       account = status.get('account');
       status  = status.get('reblog');
     }
@@ -210,6 +241,7 @@ export default class Status extends ImmutablePureComponent {
               <Component
                 preview={video.get('preview_url')}
                 src={video.get('url')}
+                alt={video.get('description')}
                 width={239}
                 height={110}
                 inline
@@ -226,11 +258,21 @@ export default class Status extends ImmutablePureComponent {
           </Bundle>
         );
       }
+    } else if (status.get('spoiler_text').length === 0 && status.get('card')) {
+      media = (
+        <Card
+          onOpenMedia={this.props.onOpenMedia}
+          card={status.get('card')}
+          compact
+        />
+      );
     }
 
-    if (account === undefined || account === null) {
+    if (otherAccounts) {
+      statusAvatar = <AvatarComposite accounts={otherAccounts} size={48} />;
+    } else if (account === undefined || account === null) {
       statusAvatar = <Avatar account={status.get('account')} size={48} />;
-    }else{
+    } else {
       statusAvatar = <AvatarOverlay account={status.get('account')} friend={account} />;
     }
 
@@ -248,10 +290,10 @@ export default class Status extends ImmutablePureComponent {
 
     return (
       <HotKeys handlers={handlers}>
-        <div className={classNames('status__wrapper', `status__wrapper-${status.get('visibility')}`, { focusable: !this.props.muted })} tabIndex={this.props.muted ? null : 0} data-featured={featured ? 'true' : null}>
+        <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'))}>
           {prepend}
 
-          <div className={classNames('status', `status-${status.get('visibility')}`, { muted: this.props.muted })} data-id={status.get('id')}>
+          <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__info'>
               <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
 
@@ -260,14 +302,20 @@ export default class Status extends ImmutablePureComponent {
                   {statusAvatar}
                 </div>
 
-                <DisplayName account={status.get('account')} />
+                <DisplayName account={status.get('account')} others={otherAccounts} />
               </a>
             </div>
 
-            <StatusContent status={status} onClick={this.handleClick} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} />
+            <StatusContent status={status} onClick={this.handleClick} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} collapsable />
 
             {media}
 
+            {showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) && (
+              <button className='status__content__read-more-button' onClick={this.handleClick}>
+                <FormattedMessage id='status.show_thread' defaultMessage='Show thread' />
+              </button>
+            )}
+
             <StatusActionBar status={status} account={account} {...other} />
           </div>
         </div>
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js
index 0ae21e3f0428b0d7e70c54a22eeae843d1088551..0995a14904c29ccd76a186738a98ecd07f929d47 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.js
@@ -5,7 +5,7 @@ import IconButton from './icon_button';
 import DropdownMenuContainer from '../containers/dropdown_menu_container';
 import { defineMessages, injectIntl } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
-import { me } from '../initial_state';
+import { me, isStaff } from '../initial_state';
 
 const messages = defineMessages({
   delete: { id: 'status.delete', defaultMessage: 'Delete' },
@@ -30,10 +30,22 @@ const messages = defineMessages({
   pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
   unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
   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' },
 });
 
-@injectIntl
-export default class StatusActionBar extends ImmutablePureComponent {
+const obfuscatedCount = count => {
+  if (count < 0) {
+    return 0;
+  } else if (count <= 1) {
+    return count;
+  } else {
+    return '1+';
+  }
+};
+
+export default @injectIntl
+class StatusActionBar extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -86,11 +98,11 @@ export default class StatusActionBar extends ImmutablePureComponent {
   }
 
   handleDeleteClick = () => {
-    this.props.onDelete(this.props.status);
+    this.props.onDelete(this.props.status, this.context.router.history);
   }
 
   handleRedraftClick = () => {
-    this.props.onDelete(this.props.status, true);
+    this.props.onDelete(this.props.status, this.context.router.history, true);
   }
 
   handlePinClick = () => {
@@ -172,6 +184,11 @@ export default 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'])}` });
+        menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
+      }
     }
 
     if (status.get('visibility') === 'direct') {
@@ -194,7 +211,7 @@ export default class StatusActionBar extends ImmutablePureComponent {
 
     return (
       <div className='status__action-bar'>
-        <IconButton className='status__action-bar-button' disabled={anonymousAccess} title={replyTitle} icon={replyIcon} onClick={this.handleReplyClick} />
+        <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} />
         {shareButton}
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js
index 4ae3b5608e45aa3f5839707d2e52b5fc011d182b..d8f18bd027c10c8cd445644e80f7c6d6d0220f14 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.js
@@ -6,6 +6,8 @@ import { FormattedMessage } from 'react-intl';
 import Permalink from './permalink';
 import classnames from 'classnames';
 
+const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
+
 export default class StatusContent extends React.PureComponent {
 
   static contextTypes = {
@@ -17,10 +19,12 @@ export default class StatusContent extends React.PureComponent {
     expanded: PropTypes.bool,
     onExpandedToggle: PropTypes.func,
     onClick: PropTypes.func,
+    collapsable: PropTypes.bool,
   };
 
   state = {
     hidden: true,
+    collapsed: null, //  `collapsed: null` indicates that an element doesn't need collapsing, while `true` or `false` indicates that it does (and is/isn't).
   };
 
   _updateStatusLinks () {
@@ -55,6 +59,16 @@ export default class StatusContent extends React.PureComponent {
       link.setAttribute('target', '_blank');
       link.setAttribute('rel', 'noopener');
     }
+
+    if (
+      this.props.collapsable
+      && this.props.onClick
+      && this.state.collapsed === null
+      && node.clientHeight > MAX_HEIGHT
+      && this.props.status.get('spoiler_text').length === 0
+    ) {
+      this.setState({ collapsed: true });
+    }
   }
 
   componentDidMount () {
@@ -66,7 +80,7 @@ export default class StatusContent extends React.PureComponent {
   }
 
   onMentionClick = (mention, e) => {
-    if (this.context.router && e.button === 0) {
+    if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
       e.preventDefault();
       this.context.router.history.push(`/accounts/${mention.get('id')}`);
     }
@@ -75,7 +89,7 @@ export default class StatusContent extends React.PureComponent {
   onHashtagClick = (hashtag, e) => {
     hashtag = hashtag.replace(/^#/, '').toLowerCase();
 
-    if (this.context.router && e.button === 0) {
+    if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
       e.preventDefault();
       this.context.router.history.push(`/timelines/tag/${hashtag}`);
     }
@@ -115,6 +129,11 @@ export default class StatusContent extends React.PureComponent {
     }
   }
 
+  handleCollapsedClick = (e) => {
+    e.preventDefault();
+    this.setState({ collapsed: !this.state.collapsed });
+  }
+
   setRef = (c) => {
     this.node = c;
   }
@@ -134,12 +153,19 @@ export default class StatusContent extends React.PureComponent {
     const classNames = classnames('status__content', {
       'status__content--with-action': this.props.onClick && this.context.router,
       'status__content--with-spoiler': status.get('spoiler_text').length > 0,
+      'status__content--collapsed': this.state.collapsed === true,
     });
 
     if (isRtl(status.get('search_index'))) {
       directionStyle.direction = 'rtl';
     }
 
+    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' />
+      </button>
+    );
+
     if (status.get('spoiler_text').length > 0) {
       let mentionsPlaceholder = '';
 
@@ -169,17 +195,24 @@ export default class StatusContent extends React.PureComponent {
         </div>
       );
     } else if (this.props.onClick) {
-      return (
+      const output = [
         <div
           ref={this.setRef}
           tabIndex='0'
+          key='content'
           className={classNames}
           style={directionStyle}
+          dangerouslySetInnerHTML={content}
           onMouseDown={this.handleMouseDown}
           onMouseUp={this.handleMouseUp}
-          dangerouslySetInnerHTML={content}
-        />
-      );
+        />,
+      ];
+
+      if (this.state.collapsed) {
+        output.push(readMoreButton);
+      }
+
+      return output;
     } else {
       return (
         <div
diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js
index 68c9eef54a8ee81c22d1f63d34beb0af65f909b4..e417f9a2b96a170b9ce2e400d4873883a38be218 100644
--- a/app/javascript/mastodon/components/status_list.js
+++ b/app/javascript/mastodon/components/status_list.js
@@ -1,12 +1,12 @@
 import { debounce } from 'lodash';
 import React from 'react';
+import { FormattedMessage } from 'react-intl';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import StatusContainer from '../containers/status_container';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import LoadGap from './load_gap';
 import ScrollableList from './scrollable_list';
-import { FormattedMessage } from 'react-intl';
 
 export default class StatusList extends ImmutablePureComponent {
 
@@ -25,7 +25,7 @@ export default class StatusList extends ImmutablePureComponent {
     prepend: PropTypes.node,
     emptyMessage: PropTypes.node,
     alwaysPrepend: PropTypes.bool,
-    timelineId: PropTypes.string.isRequired,
+    timelineId: PropTypes.string,
   };
 
   static defaultProps = {
@@ -55,7 +55,7 @@ export default class StatusList extends ImmutablePureComponent {
   }
 
   handleLoadOlder = debounce(() => {
-    this.props.onLoadMore(this.props.statusIds.last());
+    this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
   }, 300, { leading: true })
 
   _selectChild (index) {
@@ -71,7 +71,7 @@ export default class StatusList extends ImmutablePureComponent {
   }
 
   render () {
-    const { statusIds, featuredStatusIds, onLoadMore, timelineId, ...other }  = this.props;
+    const { statusIds, featuredStatusIds, shouldUpdateScroll, onLoadMore, timelineId, ...other }  = this.props;
     const { isLoading, isPartial } = other;
 
     if (isPartial) {
@@ -104,6 +104,7 @@ export default class StatusList extends ImmutablePureComponent {
           onMoveUp={this.handleMoveUp}
           onMoveDown={this.handleMoveDown}
           contextType={timelineId}
+          showThread
         />
       ))
     ) : null;
@@ -117,12 +118,13 @@ export default class StatusList extends ImmutablePureComponent {
           onMoveUp={this.handleMoveUp}
           onMoveDown={this.handleMoveDown}
           contextType={timelineId}
+          showThread
         />
       )).concat(scrollableContent);
     }
 
     return (
-      <ScrollableList {...other} onLoadMore={onLoadMore && this.handleLoadOlder} ref={this.setRef}>
+      <ScrollableList {...other} showLoading={isLoading && statusIds.size === 0} onLoadMore={onLoadMore && this.handleLoadOlder} shouldUpdateScroll={shouldUpdateScroll} ref={this.setRef}>
         {scrollableContent}
       </ScrollableList>
     );
diff --git a/app/javascript/mastodon/containers/domain_container.js b/app/javascript/mastodon/containers/domain_container.js
index 52d5c16138c227a69e9b942fe7d3c8f441ecd9b3..813178bbf662f2da01c7cc1079dfda41b2a41eab 100644
--- a/app/javascript/mastodon/containers/domain_container.js
+++ b/app/javascript/mastodon/containers/domain_container.js
@@ -10,8 +10,7 @@ const messages = defineMessages({
 });
 
 const makeMapStateToProps = () => {
-  const mapStateToProps = (state, { }) => ({
-  });
+  const mapStateToProps = () => ({});
 
   return mapStateToProps;
 };
diff --git a/app/javascript/mastodon/containers/dropdown_menu_container.js b/app/javascript/mastodon/containers/dropdown_menu_container.js
index 7cbcdcd35728f2b2cf82840a00d02d2d2545f6fd..73c8a1e530e7b0b8e285b2e7d3cca9c91c3659c4 100644
--- a/app/javascript/mastodon/containers/dropdown_menu_container.js
+++ b/app/javascript/mastodon/containers/dropdown_menu_container.js
@@ -8,15 +8,16 @@ const mapStateToProps = state => ({
   isModalOpen: state.get('modal').modalType === 'ACTIONS',
   dropdownPlacement: state.getIn(['dropdown_menu', 'placement']),
   openDropdownId: state.getIn(['dropdown_menu', 'openId']),
+  openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']),
 });
 
 const mapDispatchToProps = (dispatch, { status, items }) => ({
-  onOpen(id, onItemClick, dropdownPlacement) {
+  onOpen(id, onItemClick, dropdownPlacement, keyboard) {
     dispatch(isUserTouching() ? openModal('ACTIONS', {
       status,
       actions: items,
       onClick: onItemClick,
-    }) : openDropdownMenu(id, dropdownPlacement));
+    }) : openDropdownMenu(id, dropdownPlacement, keyboard));
   },
   onClose(id) {
     dispatch(closeModal());
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js
index b29898d3b27a1fa483144284bc6cf86784c37942..2912540a00f189e6c68238d0b9c5ffb7af90a932 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.js
@@ -1,11 +1,12 @@
 import React from 'react';
-import { Provider } from 'react-redux';
+import { Provider, connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import configureStore from '../store/configureStore';
-import { showOnboardingOnce } from '../actions/onboarding';
+import { INTRODUCTION_VERSION } from '../actions/onboarding';
 import { BrowserRouter, Route } from 'react-router-dom';
 import { ScrollContext } from 'react-router-scroll-4';
 import UI from '../features/ui';
+import Introduction from '../features/introduction';
 import { fetchCustomEmojis } from '../actions/custom_emojis';
 import { hydrateStore } from '../actions/store';
 import { connectUserStream } from '../actions/streaming';
@@ -18,34 +19,47 @@ addLocaleData(localeData);
 
 export const store = configureStore();
 const hydrateAction = hydrateStore(initialState);
-store.dispatch(hydrateAction);
 
-// load custom emojis
+store.dispatch(hydrateAction);
 store.dispatch(fetchCustomEmojis());
 
-export default class Mastodon extends React.PureComponent {
+const mapStateToProps = state => ({
+  showIntroduction: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
+});
+
+@connect(mapStateToProps)
+class MastodonMount extends React.PureComponent {
 
   static propTypes = {
-    locale: PropTypes.string.isRequired,
+    showIntroduction: PropTypes.bool,
   };
 
-  componentDidMount() {
-    this.disconnect = store.dispatch(connectUserStream());
+  render () {
+    const { showIntroduction } = this.props;
 
-    // Desktop notifications
-    // Ask after 1 minute
-    if (typeof window.Notification !== 'undefined' && Notification.permission === 'default') {
-      window.setTimeout(() => Notification.requestPermission(), 60 * 1000);
+    if (showIntroduction) {
+      return <Introduction />;
     }
 
-    // Protocol handler
-    // Ask after 5 minutes
-    if (typeof navigator.registerProtocolHandler !== 'undefined') {
-      const handlerUrl = window.location.protocol + '//' + window.location.host + '/intent?uri=%s';
-      window.setTimeout(() => navigator.registerProtocolHandler('web+mastodon', handlerUrl, 'Mastodon'), 5 * 60 * 1000);
-    }
+    return (
+      <BrowserRouter basename='/web'>
+        <ScrollContext>
+          <Route path='/' component={UI} />
+        </ScrollContext>
+      </BrowserRouter>
+    );
+  }
+
+}
 
-    store.dispatch(showOnboardingOnce());
+export default class Mastodon extends React.PureComponent {
+
+  static propTypes = {
+    locale: PropTypes.string.isRequired,
+  };
+
+  componentDidMount() {
+    this.disconnect = store.dispatch(connectUserStream());
   }
 
   componentWillUnmount () {
@@ -61,11 +75,7 @@ export default class Mastodon extends React.PureComponent {
     return (
       <IntlProvider locale={locale} messages={messages}>
         <Provider store={store}>
-          <BrowserRouter basename='/web'>
-            <ScrollContext>
-              <Route path='/' component={UI} />
-            </ScrollContext>
-          </BrowserRouter>
+          <MastodonMount />
         </Provider>
       </IntlProvider>
     );
diff --git a/app/javascript/mastodon/containers/media_container.js b/app/javascript/mastodon/containers/media_container.js
index 1700fba05a9b6bfd03e798624bf994543b6b472e..43bb394035c57d66cdfef81d52ca2e8d6d9d7121 100644
--- a/app/javascript/mastodon/containers/media_container.js
+++ b/app/javascript/mastodon/containers/media_container.js
@@ -29,19 +29,19 @@ export default class MediaContainer extends PureComponent {
   };
 
   handleOpenMedia = (media, index) => {
-    document.body.classList.add('media-standalone__body');
+    document.body.classList.add('with-modals--active');
     this.setState({ media, index });
   }
 
   handleOpenVideo = (video, time) => {
     const media = ImmutableList([video]);
 
-    document.body.classList.add('media-standalone__body');
+    document.body.classList.add('with-modals--active');
     this.setState({ media, time });
   }
 
   handleCloseMedia = () => {
-    document.body.classList.remove('media-standalone__body');
+    document.body.classList.remove('with-modals--active');
     this.setState({ media: null, index: null, time: null });
   }
 
diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js
index eb6329fdcdd2f461c1ea33145bedb2e8eb4f354d..b3555c76e550977cc3ae45bfa35789159bf09078 100644
--- a/app/javascript/mastodon/containers/status_container.js
+++ b/app/javascript/mastodon/containers/status_container.js
@@ -34,8 +34,10 @@ const messages = defineMessages({
   deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
   deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
   redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
-  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.' },
+  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: '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.' },
   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?' },
 });
 
 const makeMapStateToProps = () => {
@@ -51,7 +53,18 @@ const makeMapStateToProps = () => {
 const mapDispatchToProps = (dispatch, { intl }) => ({
 
   onReply (status, router) {
-    dispatch(replyCompose(status, router));
+    dispatch((_, getState) => {
+      let state = getState();
+      if (state.getIn(['compose', 'text']).trim().length !== 0) {
+        dispatch(openModal('CONFIRM', {
+          message: intl.formatMessage(messages.replyMessage),
+          confirm: intl.formatMessage(messages.replyConfirm),
+          onConfirm: () => dispatch(replyCompose(status, router)),
+        }));
+      } else {
+        dispatch(replyCompose(status, router));
+      }
+    });
   },
 
   onModalReblog (status) {
@@ -93,14 +106,14 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
     }));
   },
 
-  onDelete (status, withRedraft = false) {
+  onDelete (status, history, withRedraft = false) {
     if (!deleteModal) {
-      dispatch(deleteStatus(status.get('id'), withRedraft));
+      dispatch(deleteStatus(status.get('id'), history, withRedraft));
     } else {
       dispatch(openModal('CONFIRM', {
         message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
         confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
-        onConfirm: () => dispatch(deleteStatus(status.get('id'), withRedraft)),
+        onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
       }));
     }
   },
diff --git a/app/javascript/mastodon/features/account/components/action_bar.js b/app/javascript/mastodon/features/account/components/action_bar.js
index 69726a4167784b2adf781451eb372dc80cb1eef4..8ed4c917ab1510810a5936fefddc744b40f8e67e 100644
--- a/app/javascript/mastodon/features/account/components/action_bar.js
+++ b/app/javascript/mastodon/features/account/components/action_bar.js
@@ -2,9 +2,9 @@ import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
-import { Link } from 'react-router-dom';
+import { NavLink } from 'react-router-dom';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import { me } from '../../../initial_state';
+import { me, isStaff  } from '../../../initial_state';
 import { shortNumberFormat } from '../../../utils/numbers';
 
 const messages = defineMessages({
@@ -32,10 +32,14 @@ const messages = defineMessages({
   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}' },
 });
 
-@injectIntl
-export default class ActionBar extends React.PureComponent {
+export default @injectIntl
+class ActionBar extends React.PureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
@@ -48,6 +52,8 @@ export default class ActionBar extends React.PureComponent {
     onMute: PropTypes.func.isRequired,
     onBlockDomain: PropTypes.func.isRequired,
     onUnblockDomain: PropTypes.func.isRequired,
+    onEndorseToggle: PropTypes.func.isRequired,
+    onAddToList: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
   };
 
@@ -57,6 +63,13 @@ export default class ActionBar extends React.PureComponent {
     });
   }
 
+  isStatusesPageActive = (match, location) => {
+    if (!match) {
+      return false;
+    }
+    return !location.pathname.match(/\/(followers|following)\/?$/);
+  }
+
   render () {
     const { account, intl } = this.props;
 
@@ -93,6 +106,10 @@ export default class ActionBar extends React.PureComponent {
         } 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'])) {
@@ -135,26 +152,31 @@ export default class ActionBar extends React.PureComponent {
       }
     }
 
+    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'>
-            <Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}`}>
-              <span><FormattedMessage id='account.posts' defaultMessage='Toots' /></span>
+            <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>
-            </Link>
+            </NavLink>
 
-            <Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/following`}>
-              <span><FormattedMessage id='account.follows' defaultMessage='Follows' /></span>
+            <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>
-            </Link>
+            </NavLink>
 
-            <Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/followers`}>
-              <span><FormattedMessage id='account.followers' defaultMessage='Followers' /></span>
+            <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>
-            </Link>
+            </NavLink>
           </div>
 
           <div className='account__action-bar-dropdown'>
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index dd2cd406b546de5ca6011341970d9da211982e0d..2ab25cde44777cdd3096d37a973f7b02530369be 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -15,8 +15,19 @@ const messages = defineMessages({
   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.' },
 });
 
+const dateFormatOptions = {
+  month: 'short',
+  day: 'numeric',
+  year: 'numeric',
+  hour12: false,
+  hour: '2-digit',
+  minute: '2-digit',
+};
+
 class Avatar extends ImmutablePureComponent {
 
   static propTypes = {
@@ -65,8 +76,8 @@ class Avatar extends ImmutablePureComponent {
 
 }
 
-@injectIntl
-export default class Header extends ImmutablePureComponent {
+export default @injectIntl
+class Header extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map,
@@ -104,7 +115,9 @@ export default class Header extends ImmutablePureComponent {
     }
 
     if (me !== account.get('id')) {
-      if (account.getIn(['relationship', 'requested'])) {
+      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} />
@@ -136,7 +149,7 @@ export default class Header extends ImmutablePureComponent {
     }
 
     if (account.get('locked')) {
-      lockedIcon = <i className='fa fa-lock' />;
+      lockedIcon = <i className='fa fa-lock' title={intl.formatMessage(messages.account_locked)} />;
     }
 
     const content         = { __html: account.get('note_emojified') };
@@ -145,7 +158,7 @@ export default class Header extends ImmutablePureComponent {
     const badge           = account.get('bot') ? (<div className='roles'><div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div></div>) : null;
 
     return (
-      <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${account.get('header')})` }}>
+      <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${autoPlayGif ? account.get('header') : account.get('header_static')})` }}>
         <div>
           <Avatar account={account} />
 
@@ -161,7 +174,10 @@ export default class Header extends ImmutablePureComponent {
               {fields.map((pair, i) => (
                 <dl key={i}>
                   <dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} />
-                  <dd dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} title={pair.get('value_plain')} />
+
+                  <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>
               ))}
             </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 f7a802dc7949cd71542134e8157f9838152934c1..7c330c4303b6f150656c50fb542c95e3f7ed8826 100644
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.js
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js
@@ -2,7 +2,7 @@ import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import Permalink from '../../../components/permalink';
-import { displaySensitiveMedia } from '../../../initial_state';
+import { displayMedia } from '../../../initial_state';
 
 export default class MediaItem extends ImmutablePureComponent {
 
@@ -11,7 +11,7 @@ export default class MediaItem extends ImmutablePureComponent {
   };
 
   state = {
-    visible: !this.props.media.getIn(['status', 'sensitive']) || displaySensitiveMedia,
+    visible: displayMedia !== 'hide_all' && !this.props.media.getIn(['status', 'sensitive']) || displayMedia === 'show_all',
   };
 
   handleClick = () => {
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index 5f564d3a9d22206d2c4de0507e8855eb0fa84284..96051818b89665cb45873e728913b97dd38f7629 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -23,6 +23,7 @@ const mapStateToProps = (state, props) => ({
 class LoadMoreMedia extends ImmutablePureComponent {
 
   static propTypes = {
+    shouldUpdateScroll: PropTypes.func,
     maxId: PropTypes.string,
     onLoadMore: PropTypes.func.isRequired,
   };
@@ -35,15 +36,15 @@ class LoadMoreMedia extends ImmutablePureComponent {
     return (
       <LoadMore
         disabled={this.props.disabled}
-        onLoadMore={this.handleLoadMore}
+        onClick={this.handleLoadMore}
       />
     );
   }
 
 }
 
-@connect(mapStateToProps)
-export default class AccountGallery extends ImmutablePureComponent {
+export default @connect(mapStateToProps)
+class AccountGallery extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -67,7 +68,7 @@ export default class AccountGallery extends ImmutablePureComponent {
 
   handleScrollToBottom = () => {
     if (this.props.hasMore) {
-      this.handleLoadMore(this.props.medias.last().getIn(['status', 'id']));
+      this.handleLoadMore(this.props.medias.size > 0 ? this.props.medias.last().getIn(['status', 'id']) : undefined);
     }
   }
 
@@ -90,7 +91,7 @@ export default class AccountGallery extends ImmutablePureComponent {
   }
 
   render () {
-    const { medias, isLoading, hasMore } = this.props;
+    const { medias, shouldUpdateScroll, isLoading, hasMore } = this.props;
 
     let loadOlder = null;
 
@@ -102,23 +103,24 @@ export default class AccountGallery extends ImmutablePureComponent {
       );
     }
 
-    if (!isLoading && medias.size > 0 && hasMore) {
-      loadOlder = <LoadMore onClick={this.handleLoadOlder} />;
+    if (hasMore && !(isLoading && medias.size === 0)) {
+      loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />;
     }
 
     return (
       <Column>
         <ColumnBackButton />
 
-        <ScrollContainer scrollKey='account_gallery'>
-          <div className='scrollable' onScroll={this.handleScroll}>
+        <ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={shouldUpdateScroll}>
+          <div className='scrollable scrollable--flex' onScroll={this.handleScroll}>
             <HeaderContainer accountId={this.props.params.accountId} />
 
-            <div className='account-gallery__container'>
+            <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}
                 />
               ) : (
                 <MediaItem
@@ -128,6 +130,12 @@ export default class AccountGallery extends ImmutablePureComponent {
               ))}
               {loadOlder}
             </div>
+
+            {isLoading && medias.size === 0 && (
+              <div className='scrollable__append'>
+                <LoadingIndicator />
+              </div>
+            )}
           </div>
         </ScrollContainer>
       </Column>
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js
index 1ae5126e60f552eebe64ac4c7f03e0dc642f9d9d..779e116e04d79b50b7fbdcdc2e84d49632398c78 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.js
@@ -22,6 +22,8 @@ export default class Header extends ImmutablePureComponent {
     onMute: PropTypes.func.isRequired,
     onBlockDomain: PropTypes.func.isRequired,
     onUnblockDomain: PropTypes.func.isRequired,
+    onEndorseToggle: PropTypes.func.isRequired,
+    onAddToList: PropTypes.func.isRequired,
     hideTabs: PropTypes.bool,
   };
 
@@ -73,6 +75,14 @@ export default class Header extends ImmutablePureComponent {
     this.props.onUnblockDomain(domain);
   }
 
+  handleEndorseToggle = () => {
+    this.props.onEndorseToggle(this.props.account);
+  }
+
+  handleAddToList = () => {
+    this.props.onAddToList(this.props.account);
+  }
+
   render () {
     const { account, hideTabs } = this.props;
 
@@ -100,6 +110,8 @@ export default class Header extends ImmutablePureComponent {
           onMute={this.handleMute}
           onBlockDomain={this.handleBlockDomain}
           onUnblockDomain={this.handleUnblockDomain}
+          onEndorseToggle={this.handleEndorseToggle}
+          onAddToList={this.handleAddToList}
         />
 
         {!hideTabs && (
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 7681430b789175665dd92078ddd12a9dceefff1c..0fd79d036879d7641f257c16601a094fda6f520e 100644
--- a/app/javascript/mastodon/features/account_timeline/containers/header_container.js
+++ b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
@@ -8,6 +8,8 @@ import {
   blockAccount,
   unblockAccount,
   unmuteAccount,
+  pinAccount,
+  unpinAccount,
 } from '../../../actions/accounts';
 import {
   mentionCompose,
@@ -82,6 +84,14 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
     }
   },
 
+  onEndorseToggle (account) {
+    if (account.getIn(['relationship', 'endorsed'])) {
+      dispatch(unpinAccount(account.get('id')));
+    } else {
+      dispatch(pinAccount(account.get('id')));
+    }
+  },
+
   onReport (account) {
     dispatch(initReport(account));
   },
@@ -106,6 +116,12 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
     dispatch(unblockDomain(domain));
   },
 
+  onAddToList(account){
+    dispatch(openModal('LIST_ADDER', {
+      accountId: account.get('id'),
+    }));
+  },
+
 });
 
 export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header));
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js
index d329bac5c191177975589888892215ddaabd6078..afc484c607b9e9c663a884a0cd7a331273f95c97 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.js
@@ -11,6 +11,7 @@ import HeaderContainer from './containers/header_container';
 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';
 
 const mapStateToProps = (state, { params: { accountId }, withReplies = false }) => {
   const path = withReplies ? `${accountId}:with_replies` : accountId;
@@ -23,12 +24,13 @@ const mapStateToProps = (state, { params: { accountId }, withReplies = false })
   };
 };
 
-@connect(mapStateToProps)
-export default class AccountTimeline extends ImmutablePureComponent {
+export default @connect(mapStateToProps)
+class AccountTimeline extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     statusIds: ImmutablePropTypes.list,
     featuredStatusIds: ImmutablePropTypes.list,
     isLoading: PropTypes.bool,
@@ -61,7 +63,7 @@ export default class AccountTimeline extends ImmutablePureComponent {
   }
 
   render () {
-    const { statusIds, featuredStatusIds, isLoading, hasMore } = this.props;
+    const { shouldUpdateScroll, statusIds, featuredStatusIds, isLoading, hasMore } = this.props;
 
     if (!statusIds && isLoading) {
       return (
@@ -77,12 +79,15 @@ export default class AccountTimeline extends ImmutablePureComponent {
 
         <StatusList
           prepend={<HeaderContainer accountId={this.props.params.accountId} />}
+          alwaysPrepend
           scrollKey='account_timeline'
           statusIds={statusIds}
           featuredStatusIds={featuredStatusIds}
           isLoading={isLoading}
           hasMore={hasMore}
           onLoadMore={this.handleLoadMore}
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={<FormattedMessage id='empty_column.account_timeline' defaultMessage='No toots here!' />}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/blocks/index.js b/app/javascript/mastodon/features/blocks/index.js
index 14a512ae8cff28734b982831a1820055a5ea165e..ca7ce6f8ea395dc8829a5a3e3e11f1fffbcf4c9a 100644
--- a/app/javascript/mastodon/features/blocks/index.js
+++ b/app/javascript/mastodon/features/blocks/index.js
@@ -1,15 +1,16 @@
 import React from 'react';
 import { connect } from 'react-redux';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import { debounce } from 'lodash';
 import PropTypes from 'prop-types';
 import LoadingIndicator from '../../components/loading_indicator';
-import { ScrollContainer } from 'react-router-scroll-4';
 import Column from '../ui/components/column';
 import ColumnBackButtonSlim from '../../components/column_back_button_slim';
 import AccountContainer from '../../containers/account_container';
 import { fetchBlocks, expandBlocks } from '../../actions/blocks';
-import { defineMessages, injectIntl } from 'react-intl';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import ScrollableList from '../../components/scrollable_list';
 
 const messages = defineMessages({
   heading: { id: 'column.blocks', defaultMessage: 'Blocked users' },
@@ -19,13 +20,14 @@ const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'blocks', 'items']),
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class Blocks extends ImmutablePureComponent {
+class Blocks extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
     intl: PropTypes.object.isRequired,
   };
@@ -34,16 +36,12 @@ export default class Blocks extends ImmutablePureComponent {
     this.props.dispatch(fetchBlocks());
   }
 
-  handleScroll = (e) => {
-    const { scrollTop, scrollHeight, clientHeight } = e.target;
-
-    if (scrollTop === scrollHeight - clientHeight) {
-      this.props.dispatch(expandBlocks());
-    }
-  }
+  handleLoadMore = debounce(() => {
+    this.props.dispatch(expandBlocks());
+  }, 300, { leading: true });
 
   render () {
-    const { intl, accountIds } = this.props;
+    const { intl, accountIds, shouldUpdateScroll } = this.props;
 
     if (!accountIds) {
       return (
@@ -53,16 +51,21 @@ export default class Blocks extends ImmutablePureComponent {
       );
     }
 
+    const emptyMessage = <FormattedMessage id='empty_column.blocks' defaultMessage="You haven't blocked any users yet." />;
+
     return (
       <Column icon='ban' heading={intl.formatMessage(messages.heading)}>
         <ColumnBackButtonSlim />
-        <ScrollContainer scrollKey='blocks'>
-          <div className='scrollable' onScroll={this.handleScroll}>
-            {accountIds.map(id =>
-              <AccountContainer key={id} id={id} />
-            )}
-          </div>
-        </ScrollContainer>
+        <ScrollableList
+          scrollKey='blocks'
+          onLoadMore={this.handleLoadMore}
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={emptyMessage}
+        >
+          {accountIds.map(id =>
+            <AccountContainer key={id} id={id} />
+          )}
+        </ScrollableList>
       </Column>
     );
   }
diff --git a/app/javascript/mastodon/features/community_timeline/components/column_settings.js b/app/javascript/mastodon/features/community_timeline/components/column_settings.js
index f4325f58d31bf94ad055d53a7b188d6d11511ff5..8250190a7adf1ebbc6aa88a24d22de8392d7cd7a 100644
--- a/app/javascript/mastodon/features/community_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/community_timeline/components/column_settings.js
@@ -4,8 +4,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import { injectIntl, FormattedMessage } from 'react-intl';
 import SettingToggle from '../../notifications/components/setting_toggle';
 
-@injectIntl
-export default class ColumnSettings extends React.PureComponent {
+export default @injectIntl
+class ColumnSettings extends React.PureComponent {
 
   static propTypes = {
     settings: ImmutablePropTypes.map.isRequired,
diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.js
index eb9ad97a2bd1bd35ae73a42cb8cf497260d91db6..7d26c98b0d30de457d75ddc02bed8ea626c7d609 100644
--- a/app/javascript/mastodon/features/community_timeline/index.js
+++ b/app/javascript/mastodon/features/community_timeline/index.js
@@ -25,9 +25,9 @@ const mapStateToProps = (state, { onlyMedia, columnId }) => {
   };
 };
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class CommunityTimeline extends React.PureComponent {
+class CommunityTimeline extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -39,6 +39,7 @@ export default class CommunityTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     columnId: PropTypes.string,
     intl: PropTypes.object.isRequired,
     hasUnread: PropTypes.bool,
@@ -100,11 +101,11 @@ export default class CommunityTimeline extends React.PureComponent {
   }
 
   render () {
-    const { intl, hasUnread, columnId, multiColumn, onlyMedia } = this.props;
+    const { intl, shouldUpdateScroll, hasUnread, columnId, multiColumn, onlyMedia } = this.props;
     const pinned = !!columnId;
 
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
         <ColumnHeader
           icon='users'
           active={hasUnread}
@@ -124,6 +125,7 @@ export default class CommunityTimeline extends React.PureComponent {
           timelineId={`community${onlyMedia ? ':media' : ''}`}
           onLoadMore={this.handleLoadMore}
           emptyMessage={<FormattedMessage id='empty_column.community' defaultMessage='The local timeline is empty. Write something publicly to get the ball rolling!' />}
+          shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/compose/components/action_bar.js b/app/javascript/mastodon/features/compose/components/action_bar.js
index daee18552ac29b7c02f721225a96b7cca0de3e63..95d6eeb06d03a657e2721ed5666838e960aacd74 100644
--- a/app/javascript/mastodon/features/compose/components/action_bar.js
+++ b/app/javascript/mastodon/features/compose/components/action_bar.js
@@ -17,8 +17,8 @@ const messages = defineMessages({
   filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
 });
 
-@injectIntl
-export default class ActionBar extends React.PureComponent {
+export default @injectIntl
+class ActionBar extends React.PureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index 1a1c57ba8143e8516214f84e7cca633223ccdaf0..16ed044024dba0136eb82a789f536d8b73af32b4 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -27,8 +27,12 @@ const messages = defineMessages({
   publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
 });
 
-@injectIntl
-export default class ComposeForm extends ImmutablePureComponent {
+export default @injectIntl
+class ComposeForm extends ImmutablePureComponent {
+
+  static contextTypes = {
+    router: PropTypes.object,
+  };
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
@@ -42,6 +46,7 @@ export default class ComposeForm extends ImmutablePureComponent {
     caretPosition: PropTypes.number,
     preselectDate: PropTypes.instanceOf(Date),
     is_submitting: PropTypes.bool,
+    is_changing_upload: PropTypes.bool,
     is_uploading: PropTypes.bool,
     onChange: PropTypes.func.isRequired,
     onSubmit: PropTypes.func.isRequired,
@@ -77,14 +82,14 @@ export default class ComposeForm extends ImmutablePureComponent {
     }
 
     // Submit disabled:
-    const { is_submitting, is_uploading, anyMedia } = this.props;
+    const { is_submitting, is_changing_upload, is_uploading, anyMedia } = this.props;
     const fulltext = [this.props.spoiler_text, countableText(this.props.text)].join('');
 
-    if (is_submitting || is_uploading || length(fulltext) > 65535 || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
+    if (is_submitting || is_uploading || is_changing_upload || length(fulltext) > 65535 || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
       return;
     }
 
-    this.props.onSubmit();
+    this.props.onSubmit(this.context.router ? this.context.router.history : null);
   }
 
   onSuggestionsClearRequested = () => {
@@ -156,7 +161,7 @@ export default class ComposeForm extends ImmutablePureComponent {
     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 || length(text) > 65535 || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
+    const disabledButton = disabled || this.props.is_uploading || this.props.is_changing_upload || length(text) > 65535 || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
     let publishText = '';
 
     if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
index 4fc32db8a4d5debd12de66c6fead3b2a9473ff9f..c1429c756fdbefb2e802592c543fb418a5adb951 100644
--- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
@@ -261,6 +261,7 @@ class EmojiPickerMenu extends React.PureComponent {
           skin={skinTone}
           showPreview={false}
           backgroundImageFn={backgroundImageFn}
+          autoFocus
           emojiTooltip
         />
 
@@ -277,8 +278,8 @@ class EmojiPickerMenu extends React.PureComponent {
 
 }
 
-@injectIntl
-export default class EmojiPickerDropdown extends React.PureComponent {
+export default @injectIntl
+class EmojiPickerDropdown extends React.PureComponent {
 
   static propTypes = {
     custom_emojis: ImmutablePropTypes.list,
diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
index a772c1c953b750c525a41c5332087fef2a16fdd7..5698765d94f2b55e54ac9f328f2df6f08235c3dd 100644
--- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
@@ -28,6 +28,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
     style: PropTypes.object,
     items: PropTypes.array.isRequired,
     value: PropTypes.string.isRequired,
+    placement: PropTypes.string.isRequired,
     onClose: PropTypes.func.isRequired,
     onChange: PropTypes.func.isRequired,
   };
@@ -119,7 +120,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
 
   render () {
     const { mounted } = this.state;
-    const { style, items, value } = this.props;
+    const { style, items, placement, value } = this.props;
 
     return (
       <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 }) }}>
@@ -127,7 +128,7 @@ 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' 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 }} 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'>
@@ -148,8 +149,8 @@ class PrivacyDropdownMenu extends React.PureComponent {
 
 }
 
-@injectIntl
-export default class PrivacyDropdown extends React.PureComponent {
+export default @injectIntl
+class PrivacyDropdown extends React.PureComponent {
 
   static propTypes = {
     isUserTouching: PropTypes.func,
@@ -163,7 +164,7 @@ export default class PrivacyDropdown extends React.PureComponent {
 
   state = {
     open: false,
-    placement: null,
+    placement: 'bottom',
   };
 
   handleToggle = ({ target }) => {
@@ -226,7 +227,7 @@ export default class PrivacyDropdown extends React.PureComponent {
     const valueOption = this.options.find(item => item.value === value);
 
     return (
-      <div className={classNames('privacy-dropdown', { active: open })} onKeyDown={this.handleKeyDown}>
+      <div className={classNames('privacy-dropdown', placement, { active: open })} onKeyDown={this.handleKeyDown}>
         <div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === 0 })}>
           <IconButton
             className='privacy-dropdown__value-icon'
@@ -247,6 +248,7 @@ export default class PrivacyDropdown extends React.PureComponent {
             value={value}
             onClose={this.handleClose}
             onChange={this.handleChange}
+            placement={placement}
           />
         </Overlay>
       </div>
diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.js
index 5b4b81eac7f060a06ba963c26bf8ed5e1ad51399..142223f3d8a223d3d6f29dc76038d858d16706b4 100644
--- a/app/javascript/mastodon/features/compose/components/reply_indicator.js
+++ b/app/javascript/mastodon/features/compose/components/reply_indicator.js
@@ -12,8 +12,8 @@ const messages = defineMessages({
   cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
 });
 
-@injectIntl
-export default class ReplyIndicator extends ImmutablePureComponent {
+export default @injectIntl
+class ReplyIndicator extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -30,7 +30,7 @@ export default class ReplyIndicator extends ImmutablePureComponent {
   }
 
   handleAccountClick = (e) => {
-    if (e.button === 0) {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
       e.preventDefault();
       this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
     }
diff --git a/app/javascript/mastodon/features/compose/components/search.js b/app/javascript/mastodon/features/compose/components/search.js
index 71c0a203f0d033fe037322680a2b48686dc5f8cb..d203d87800930e908d54d97df0dffd7f0cfb56bd 100644
--- a/app/javascript/mastodon/features/compose/components/search.js
+++ b/app/javascript/mastodon/features/compose/components/search.js
@@ -43,8 +43,8 @@ class SearchPopout extends React.PureComponent {
 
 }
 
-@injectIntl
-export default class Search extends React.PureComponent {
+export default @injectIntl
+class Search extends React.PureComponent {
 
   static propTypes = {
     value: PropTypes.string.isRequired,
diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.js
index c351b84bb3ee5fff991f2d45bd5075867a181860..f0ddf6d7144bf9b35f7ff2a2e3012520a26472fd 100644
--- a/app/javascript/mastodon/features/compose/components/search_results.js
+++ b/app/javascript/mastodon/features/compose/components/search_results.js
@@ -1,19 +1,56 @@
 import React from 'react';
+import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
-import { FormattedMessage } from 'react-intl';
+import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
 import AccountContainer from '../../../containers/account_container';
 import StatusContainer from '../../../containers/status_container';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import Hashtag from '../../../components/hashtag';
 
-export default class SearchResults extends ImmutablePureComponent {
+const messages = defineMessages({
+  dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
+});
+
+export default @injectIntl
+class SearchResults extends ImmutablePureComponent {
 
   static propTypes = {
     results: ImmutablePropTypes.map.isRequired,
+    suggestions: ImmutablePropTypes.list.isRequired,
+    fetchSuggestions: PropTypes.func.isRequired,
+    dismissSuggestion: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
   };
 
+  componentDidMount () {
+    this.props.fetchSuggestions();
+  }
+
   render () {
-    const { results } = this.props;
+    const { intl, results, suggestions, dismissSuggestion } = 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' />
+              <FormattedMessage id='suggestions.header' defaultMessage='You might be interested in…' />
+            </div>
+
+            {suggestions && suggestions.map(accountId => (
+              <AccountContainer
+                key={accountId}
+                id={accountId}
+                actionIcon='times'
+                actionTitle={intl.formatMessage(messages.dismissSuggestion)}
+                onActionClick={dismissSuggestion}
+              />
+            ))}
+          </div>
+        </div>
+      );
+    }
 
     let accounts, statuses, hashtags;
     let count = 0;
diff --git a/app/javascript/mastodon/features/compose/components/upload.js b/app/javascript/mastodon/features/compose/components/upload.js
index bfa2b47271a6b59f3860f66cae4b9cb9357d2506..a1e99dcbbdbca3346ec4e90d428fb7590d7ae0c7 100644
--- a/app/javascript/mastodon/features/compose/components/upload.js
+++ b/app/javascript/mastodon/features/compose/components/upload.js
@@ -11,8 +11,12 @@ const messages = defineMessages({
   description: { id: 'upload_form.description', defaultMessage: 'Describe for the visually impaired' },
 });
 
-@injectIntl
-export default class Upload extends ImmutablePureComponent {
+export default @injectIntl
+class Upload extends ImmutablePureComponent {
+
+  static contextTypes = {
+    router: PropTypes.object,
+  };
 
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
@@ -20,6 +24,7 @@ export default class Upload extends ImmutablePureComponent {
     onUndo: PropTypes.func.isRequired,
     onDescriptionChange: PropTypes.func.isRequired,
     onOpenFocalPoint: PropTypes.func.isRequired,
+    onSubmit: PropTypes.func.isRequired,
   };
 
   state = {
@@ -28,11 +33,24 @@ export default class Upload extends ImmutablePureComponent {
     dirtyDescription: null,
   };
 
-  handleUndoClick = () => {
+  handleKeyDown = (e) => {
+    if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
+      this.handleSubmit();
+    }
+  }
+
+  handleSubmit = () => {
+    this.handleInputBlur();
+    this.props.onSubmit(this.context.router.history);
+  }
+
+  handleUndoClick = e => {
+    e.stopPropagation();
     this.props.onUndo(this.props.media.get('id'));
   }
 
-  handleFocalPointClick = () => {
+  handleFocalPointClick = e => {
+    e.stopPropagation();
     this.props.onOpenFocalPoint(this.props.media.get('id'));
   }
 
@@ -52,6 +70,10 @@ export default class Upload extends ImmutablePureComponent {
     this.setState({ focused: true });
   }
 
+  handleClick = () => {
+    this.setState({ focused: true });
+  }
+
   handleInputBlur = () => {
     const { dirtyDescription } = this.state;
 
@@ -72,7 +94,7 @@ export default class Upload extends ImmutablePureComponent {
     const y = ((focusY / -2) + .5) * 100;
 
     return (
-      <div className='compose-form__upload' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
+      <div className='compose-form__upload' tabIndex='0' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} onClick={this.handleClick} role='button'>
         <Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
           {({ scale }) => (
             <div className='compose-form__upload-thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}>
@@ -93,6 +115,7 @@ export default class Upload extends ImmutablePureComponent {
                     onFocus={this.handleInputFocus}
                     onChange={this.handleInputChange}
                     onBlur={this.handleInputBlur}
+                    onKeyDown={this.handleKeyDown}
                   />
                 </label>
               </div>
diff --git a/app/javascript/mastodon/features/compose/components/upload_button.js b/app/javascript/mastodon/features/compose/components/upload_button.js
index 70b28a2baeb27fbd9b742c16e9533c226704aa47..b6fe770eada75e214e62980d4026aa7e37aaa45e 100644
--- a/app/javascript/mastodon/features/compose/components/upload_button.js
+++ b/app/javascript/mastodon/features/compose/components/upload_button.js
@@ -7,7 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 
 const messages = defineMessages({
-  upload: { id: 'upload_button.label', defaultMessage: 'Add media' },
+  upload: { id: 'upload_button.label', defaultMessage: 'Add media (JPEG, PNG, GIF, WebM, MP4, MOV)' },
 });
 
 const makeMapStateToProps = () => {
@@ -23,9 +23,9 @@ const iconStyle = {
   lineHeight: '27px',
 };
 
-@connect(makeMapStateToProps)
+export default @connect(makeMapStateToProps)
 @injectIntl
-export default class UploadButton extends ImmutablePureComponent {
+class UploadButton extends ImmutablePureComponent {
 
   static propTypes = {
     disabled: PropTypes.bool,
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 3822dd711fe32e0eaa2c610bab0b89faaa1b8091..b4a1c4b44462e4a37dcd7f8dfb7cdf206ddaf4f6 100644
--- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js
+++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
@@ -22,6 +22,7 @@ const mapStateToProps = state => ({
   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']),
   showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
   anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
@@ -33,8 +34,8 @@ const mapDispatchToProps = (dispatch) => ({
     dispatch(changeCompose(text));
   },
 
-  onSubmit () {
-    dispatch(submitCompose());
+  onSubmit (router) {
+    dispatch(submitCompose(router));
   },
 
   onClearSuggestions () {
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 16d95d417e4a501126a16fb55afa795133a04911..f9637861ae7b437c632f10f0967590f0e98df3b3 100644
--- a/app/javascript/mastodon/features/compose/containers/search_results_container.js
+++ b/app/javascript/mastodon/features/compose/containers/search_results_container.js
@@ -1,8 +1,15 @@
 import { connect } from 'react-redux';
 import SearchResults from '../components/search_results';
+import { fetchSuggestions, dismissSuggestion } from '../../../actions/suggestions';
 
 const mapStateToProps = state => ({
   results: state.getIn(['search', 'results']),
+  suggestions: state.getIn(['suggestions', 'items']),
 });
 
-export default connect(mapStateToProps)(SearchResults);
+const mapDispatchToProps = dispatch => ({
+  fetchSuggestions: () => dispatch(fetchSuggestions()),
+  dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(SearchResults);
diff --git a/app/javascript/mastodon/features/compose/containers/upload_container.js b/app/javascript/mastodon/features/compose/containers/upload_container.js
index d6b57e5ffbbaadf995c7fcb306adbfe758602036..b6d81f03ac6d9cf387f3e23d296f59f1d3c1b596 100644
--- a/app/javascript/mastodon/features/compose/containers/upload_container.js
+++ b/app/javascript/mastodon/features/compose/containers/upload_container.js
@@ -2,6 +2,7 @@ import { connect } from 'react-redux';
 import Upload from '../components/upload';
 import { undoUploadCompose, changeUploadCompose } from '../../../actions/compose';
 import { openModal } from '../../../actions/modal';
+import { submitCompose } from '../../../actions/compose';
 
 const mapStateToProps = (state, { id }) => ({
   media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
@@ -21,6 +22,10 @@ const mapDispatchToProps = dispatch => ({
     dispatch(openModal('FOCAL_POINT', { id }));
   },
 
+  onSubmit (router) {
+    dispatch(submitCompose(router));
+  },
+
 });
 
 export default connect(mapStateToProps, mapDispatchToProps)(Upload);
diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js
index df1ec491500de1c1b14280e1f5c2cac5ce2a1a9a..d76cd76e61be2bdd3816e2cdb81217a007fe7bdc 100644
--- a/app/javascript/mastodon/features/compose/index.js
+++ b/app/javascript/mastodon/features/compose/index.js
@@ -13,6 +13,7 @@ import spring from 'react-motion/lib/spring';
 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';
 
 const messages = defineMessages({
   start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
@@ -22,6 +23,7 @@ const messages = defineMessages({
   community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
   preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
   logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
+  compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' },
 });
 
 const mapStateToProps = (state, ownProps) => ({
@@ -29,9 +31,9 @@ const mapStateToProps = (state, ownProps) => ({
   showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : ownProps.isSearchPage,
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class Compose extends React.PureComponent {
+class Compose extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -95,7 +97,7 @@ export default class Compose extends React.PureComponent {
     }
 
     return (
-      <div className='drawer'>
+      <div className='drawer' role='region' aria-label={intl.formatMessage(messages.compose)}>
         {header}
 
         {(multiColumn || isSearchPage) && <SearchContainer /> }
@@ -106,7 +108,7 @@ export default class Compose extends React.PureComponent {
             <ComposeFormContainer />
             {multiColumn && (
               <div className='drawer__inner__mastodon'>
-                <img alt='' draggable='false' src={elephantUIPlane} />
+                <img alt='' draggable='false' src={mascot || elephantUIPlane} />
               </div>
             )}
           </div>}
diff --git a/app/javascript/mastodon/features/compose/util/url_regex.js b/app/javascript/mastodon/features/compose/util/url_regex.js
index d5e39e0d5137cf031bb779f702185a8a34954132..7f1e176207b0bc1e6d556cba9d6cd768bf369149 100644
--- a/app/javascript/mastodon/features/compose/util/url_regex.js
+++ b/app/javascript/mastodon/features/compose/util/url_regex.js
@@ -170,7 +170,7 @@ export const urlRegex = (function() {
       ')'                                   +
     '\\)',
     'i');
-  // Valid end-of-path chracters (so /foo. does not gobble the period).
+  // Valid end-of-path characters (so /foo. does not gobble the period).
   // 1. Allow =&# for empty URL parameters and other URL-join artifacts
   regexen.validUrlPathEndingChars = regexSupplant(/[^#{spaces_group}\(\)\?!\*';:=\,\.\$%\[\]#{pd}~&\|@]|(?:#{validUrlBalancedParens})/i);
   // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/
diff --git a/app/javascript/mastodon/features/direct_timeline/components/column_settings.js b/app/javascript/mastodon/features/direct_timeline/components/column_settings.js
index a992b27bbdb458007d9b66e8653adce6dcf04985..b629c128dd8ae898eaa774d60bf9b998b8eb828f 100644
--- a/app/javascript/mastodon/features/direct_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/direct_timeline/components/column_settings.js
@@ -9,8 +9,8 @@ const messages = defineMessages({
   settings: { id: 'home.settings', defaultMessage: 'Column settings' },
 });
 
-@injectIntl
-export default class ColumnSettings extends React.PureComponent {
+export default @injectIntl
+class ColumnSettings extends React.PureComponent {
 
   static propTypes = {
     settings: ImmutablePropTypes.map.isRequired,
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.js b/app/javascript/mastodon/features/direct_timeline/components/conversation.js
new file mode 100644
index 0000000000000000000000000000000000000000..ffcd6d2811af8ac082a4cee79051e5073f2377c8
--- /dev/null
+++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.js
@@ -0,0 +1,64 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import StatusContainer from '../../../containers/status_container';
+
+export default class Conversation extends ImmutablePureComponent {
+
+  static contextTypes = {
+    router: PropTypes.object,
+  };
+
+  static propTypes = {
+    conversationId: PropTypes.string.isRequired,
+    accounts: ImmutablePropTypes.list.isRequired,
+    lastStatusId: PropTypes.string,
+    unread:PropTypes.bool.isRequired,
+    onMoveUp: PropTypes.func,
+    onMoveDown: PropTypes.func,
+    markRead: PropTypes.func.isRequired,
+  };
+
+  handleClick = () => {
+    if (!this.context.router) {
+      return;
+    }
+
+    const { lastStatusId, unread, markRead } = this.props;
+
+    if (unread) {
+      markRead();
+    }
+
+    this.context.router.history.push(`/statuses/${lastStatusId}`);
+  }
+
+  handleHotkeyMoveUp = () => {
+    this.props.onMoveUp(this.props.conversationId);
+  }
+
+  handleHotkeyMoveDown = () => {
+    this.props.onMoveDown(this.props.conversationId);
+  }
+
+  render () {
+    const { accounts, lastStatusId, unread } = this.props;
+
+    if (lastStatusId === null) {
+      return null;
+    }
+
+    return (
+      <StatusContainer
+        id={lastStatusId}
+        unread={unread}
+        otherAccounts={accounts}
+        onMoveUp={this.handleHotkeyMoveUp}
+        onMoveDown={this.handleHotkeyMoveDown}
+        onClick={this.handleClick}
+      />
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js b/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js
new file mode 100644
index 0000000000000000000000000000000000000000..635c03c1d129c4d0e64eb74f06e0cf51bdd407bf
--- /dev/null
+++ b/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js
@@ -0,0 +1,68 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import ConversationContainer from '../containers/conversation_container';
+import ScrollableList from '../../../components/scrollable_list';
+import { debounce } from 'lodash';
+
+export default class ConversationsList extends ImmutablePureComponent {
+
+  static propTypes = {
+    conversations: ImmutablePropTypes.list.isRequired,
+    hasMore: PropTypes.bool,
+    isLoading: PropTypes.bool,
+    onLoadMore: PropTypes.func,
+    shouldUpdateScroll: PropTypes.func,
+  };
+
+  getCurrentIndex = id => this.props.conversations.findIndex(x => x.get('id') === id)
+
+  handleMoveUp = id => {
+    const elementIndex = this.getCurrentIndex(id) - 1;
+    this._selectChild(elementIndex);
+  }
+
+  handleMoveDown = id => {
+    const elementIndex = this.getCurrentIndex(id) + 1;
+    this._selectChild(elementIndex);
+  }
+
+  _selectChild (index) {
+    const element = this.node.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
+
+    if (element) {
+      element.focus();
+    }
+  }
+
+  setRef = c => {
+    this.node = c;
+  }
+
+  handleLoadOlder = debounce(() => {
+    const last = this.props.conversations.last();
+
+    if (last && last.get('last_status')) {
+      this.props.onLoadMore(last.get('last_status'));
+    }
+  }, 300, { leading: true })
+
+  render () {
+    const { conversations, onLoadMore, ...other } = this.props;
+
+    return (
+      <ScrollableList {...other} onLoadMore={onLoadMore && this.handleLoadOlder} scrollKey='direct' ref={this.setRef}>
+        {conversations.map(item => (
+          <ConversationContainer
+            key={item.get('id')}
+            conversationId={item.get('id')}
+            onMoveUp={this.handleMoveUp}
+            onMoveDown={this.handleMoveDown}
+          />
+        ))}
+      </ScrollableList>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/direct_timeline/containers/conversation_container.js b/app/javascript/mastodon/features/direct_timeline/containers/conversation_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..bd6f6bfb0176ce45ff43f85c883f06bf4e03f6c4
--- /dev/null
+++ b/app/javascript/mastodon/features/direct_timeline/containers/conversation_container.js
@@ -0,0 +1,19 @@
+import { connect } from 'react-redux';
+import Conversation from '../components/conversation';
+import { markConversationRead } from '../../../actions/conversations';
+
+const mapStateToProps = (state, { conversationId }) => {
+  const conversation = state.getIn(['conversations', 'items']).find(x => x.get('id') === conversationId);
+
+  return {
+    accounts: conversation.get('accounts').map(accountId => state.getIn(['accounts', accountId], null)),
+    unread: conversation.get('unread'),
+    lastStatusId: conversation.get('last_status', null),
+  };
+};
+
+const mapDispatchToProps = (dispatch, { conversationId }) => ({
+  markRead: () => dispatch(markConversationRead(conversationId)),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(Conversation);
diff --git a/app/javascript/mastodon/features/direct_timeline/containers/conversations_list_container.js b/app/javascript/mastodon/features/direct_timeline/containers/conversations_list_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..57e17d96f7c58d50da2f8f0c474283ee871a8556
--- /dev/null
+++ b/app/javascript/mastodon/features/direct_timeline/containers/conversations_list_container.js
@@ -0,0 +1,15 @@
+import { connect } from 'react-redux';
+import ConversationsList from '../components/conversations_list';
+import { expandConversations } from '../../../actions/conversations';
+
+const mapStateToProps = state => ({
+  conversations: state.getIn(['conversations', 'items']),
+  isLoading: state.getIn(['conversations', 'isLoading'], true),
+  hasMore: state.getIn(['conversations', 'hasMore'], false),
+});
+
+const mapDispatchToProps = dispatch => ({
+  onLoadMore: maxId => dispatch(expandConversations({ maxId })),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(ConversationsList);
diff --git a/app/javascript/mastodon/features/direct_timeline/index.js b/app/javascript/mastodon/features/direct_timeline/index.js
index 63dc41d9e77849e6f3a5892d62287cc5ed3aa048..d202f3bfd904d86255010f995615399fe4978f41 100644
--- a/app/javascript/mastodon/features/direct_timeline/index.js
+++ b/app/javascript/mastodon/features/direct_timeline/index.js
@@ -1,28 +1,25 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
-import StatusListContainer from '../ui/containers/status_list_container';
 import Column from '../../components/column';
 import ColumnHeader from '../../components/column_header';
-import { expandDirectTimeline } from '../../actions/timelines';
+import { mountConversations, unmountConversations, expandConversations } from '../../actions/conversations';
 import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { connectDirectStream } from '../../actions/streaming';
+import ConversationsListContainer from './containers/conversations_list_container';
 
 const messages = defineMessages({
   title: { id: 'column.direct', defaultMessage: 'Direct messages' },
 });
 
-const mapStateToProps = state => ({
-  hasUnread: state.getIn(['timelines', 'direct', 'unread']) > 0,
-});
-
-@connect(mapStateToProps)
+export default @connect()
 @injectIntl
-export default class DirectTimeline extends React.PureComponent {
+class DirectTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     columnId: PropTypes.string,
     intl: PropTypes.object.isRequired,
     hasUnread: PropTypes.bool,
@@ -51,11 +48,14 @@ export default class DirectTimeline extends React.PureComponent {
   componentDidMount () {
     const { dispatch } = this.props;
 
-    dispatch(expandDirectTimeline());
+    dispatch(mountConversations());
+    dispatch(expandConversations());
     this.disconnect = dispatch(connectDirectStream());
   }
 
   componentWillUnmount () {
+    this.props.dispatch(unmountConversations());
+
     if (this.disconnect) {
       this.disconnect();
       this.disconnect = null;
@@ -67,15 +67,15 @@ export default class DirectTimeline extends React.PureComponent {
   }
 
   handleLoadMore = maxId => {
-    this.props.dispatch(expandDirectTimeline({ maxId }));
+    this.props.dispatch(expandConversations({ maxId }));
   }
 
   render () {
-    const { intl, hasUnread, columnId, multiColumn } = this.props;
+    const { intl, hasUnread, columnId, multiColumn, shouldUpdateScroll } = this.props;
     const pinned = !!columnId;
 
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
         <ColumnHeader
           icon='envelope'
           active={hasUnread}
@@ -87,12 +87,13 @@ export default class DirectTimeline extends React.PureComponent {
           multiColumn={multiColumn}
         />
 
-        <StatusListContainer
+        <ConversationsListContainer
           trackScroll={!pinned}
           scrollKey={`direct_timeline-${columnId}`}
           timelineId='direct'
           onLoadMore={this.handleLoadMore}
           emptyMessage={<FormattedMessage id='empty_column.direct' defaultMessage="You don't have any direct messages yet. When you send or receive one, it will show up here." />}
+          shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/domain_blocks/index.js b/app/javascript/mastodon/features/domain_blocks/index.js
index b8a942d6c26da70c59e4294f1b4b8587935487d4..5c1bd11610ca7a70c065322a73e483843a4df127 100644
--- a/app/javascript/mastodon/features/domain_blocks/index.js
+++ b/app/javascript/mastodon/features/domain_blocks/index.js
@@ -1,15 +1,15 @@
 import React from 'react';
 import { connect } from 'react-redux';
-import ImmutablePropTypes from 'react-immutable-proptypes';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { debounce } from 'lodash';
 import LoadingIndicator from '../../components/loading_indicator';
 import Column from '../ui/components/column';
 import ColumnBackButtonSlim from '../../components/column_back_button_slim';
 import DomainContainer from '../../containers/domain_container';
 import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
-import { defineMessages, injectIntl } from 'react-intl';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-import { debounce } from 'lodash';
 import ScrollableList from '../../components/scrollable_list';
 
 const messages = defineMessages({
@@ -21,13 +21,14 @@ const mapStateToProps = state => ({
   domains: state.getIn(['domain_lists', 'blocks', 'items']),
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class Blocks extends ImmutablePureComponent {
+class Blocks extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     domains: ImmutablePropTypes.orderedSet,
     intl: PropTypes.object.isRequired,
   };
@@ -41,7 +42,7 @@ export default class Blocks extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { intl, domains } = this.props;
+    const { intl, domains, shouldUpdateScroll } = this.props;
 
     if (!domains) {
       return (
@@ -51,10 +52,17 @@ export default class Blocks extends ImmutablePureComponent {
       );
     }
 
+    const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no hidden domains yet.' />;
+
     return (
       <Column icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
         <ColumnBackButtonSlim />
-        <ScrollableList scrollKey='domain_blocks' onLoadMore={this.handleLoadMore}>
+        <ScrollableList
+          scrollKey='domain_blocks'
+          onLoadMore={this.handleLoadMore}
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={emptyMessage}
+        >
           {domains.map(domain =>
             <DomainContainer key={domain} domain={domain} />
           )}
diff --git a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
index d91b4849754e1c54715d2ad32b9eb871c86bbda0..c8425c4c6db63e3a0fd2de969daf8a090179f465 100644
--- a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
+++ b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
@@ -73,5 +73,10 @@ describe('emoji', () => {
       expect(emojify('<span class="invisible">😄<br/>😴</span>😇'))
         .toEqual('<span class="invisible">😄<br/>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg" />');
     });
+
+    it('skips the textual presentation VS15 character', () => {
+      expect(emojify('✴︎')) // This is U+2734 EIGHT POINTED BLACK STAR then U+FE0E VARIATION SELECTOR-15
+        .toEqual('<img draggable="false" class="emojione" alt="✴" title=":eight_pointed_black_star:" src="/emoji/2734.svg" />');
+    });
   });
 });
diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js
index 0f005dd5040d130f893da285831b1ab29dd7eee1..988cea2530d1e6f7a9b799dc4c3141343eba3583 100644
--- a/app/javascript/mastodon/features/emoji/emoji.js
+++ b/app/javascript/mastodon/features/emoji/emoji.js
@@ -62,6 +62,10 @@ const emojify = (str, customEmojis = {}) => {
       const title = shortCode ? `:${shortCode}:` : '';
       replacement = `<img draggable="false" class="emojione" alt="${match}" title="${title}" src="${assetHost}/emoji/${filename}.svg" />`;
       rend = i + match.length;
+      // If the matched character was followed by VS15 (for selecting text presentation), skip it.
+      if (str.codePointAt(rend) === 65038) {
+        rend += 1;
+      }
     }
     rtn += str.slice(0, i) + replacement;
     str = str.slice(rend);
diff --git a/app/javascript/mastodon/features/emoji/emoji_map.json b/app/javascript/mastodon/features/emoji/emoji_map.json
index 13753ba84cc83b157d829c8e6c4d375b63e27b4a..d46dc82ad89c6aae2b6b4a75229f01d92efc02de 100644
--- a/app/javascript/mastodon/features/emoji/emoji_map.json
+++ b/app/javascript/mastodon/features/emoji/emoji_map.json
@@ -1 +1 @@
-{"😀":"1f600","😁":"1f601","😂":"1f602","🤣":"1f923","😃":"1f603","😄":"1f604","😅":"1f605","😆":"1f606","😉":"1f609","😊":"1f60a","😋":"1f60b","😎":"1f60e","😍":"1f60d","😘":"1f618","😗":"1f617","😙":"1f619","😚":"1f61a","☺":"263a","🙂":"1f642","🤗":"1f917","🤩":"1f929","🤔":"1f914","🤨":"1f928","😐":"1f610","😑":"1f611","😶":"1f636","🙄":"1f644","😏":"1f60f","😣":"1f623","😥":"1f625","😮":"1f62e","🤐":"1f910","😯":"1f62f","😪":"1f62a","😫":"1f62b","😴":"1f634","😌":"1f60c","😛":"1f61b","😜":"1f61c","😝":"1f61d","🤤":"1f924","😒":"1f612","😓":"1f613","😔":"1f614","😕":"1f615","🙃":"1f643","🤑":"1f911","😲":"1f632","☹":"2639","🙁":"1f641","😖":"1f616","😞":"1f61e","😟":"1f61f","😤":"1f624","😢":"1f622","😭":"1f62d","😦":"1f626","😧":"1f627","😨":"1f628","😩":"1f629","🤯":"1f92f","😬":"1f62c","😰":"1f630","😱":"1f631","😳":"1f633","🤪":"1f92a","😵":"1f635","😡":"1f621","😠":"1f620","🤬":"1f92c","😷":"1f637","🤒":"1f912","🤕":"1f915","🤢":"1f922","🤮":"1f92e","🤧":"1f927","😇":"1f607","🤠":"1f920","🤡":"1f921","🤥":"1f925","🤫":"1f92b","🤭":"1f92d","🧐":"1f9d0","🤓":"1f913","😈":"1f608","👿":"1f47f","👹":"1f479","👺":"1f47a","💀":"1f480","☠":"2620","👻":"1f47b","👽":"1f47d","👾":"1f47e","🤖":"1f916","💩":"1f4a9","😺":"1f63a","😸":"1f638","😹":"1f639","😻":"1f63b","😼":"1f63c","😽":"1f63d","🙀":"1f640","😿":"1f63f","😾":"1f63e","🙈":"1f648","🙉":"1f649","🙊":"1f64a","👶":"1f476","🧒":"1f9d2","👦":"1f466","👧":"1f467","🧑":"1f9d1","👨":"1f468","👩":"1f469","🧓":"1f9d3","👴":"1f474","👵":"1f475","👮":"1f46e","🕵":"1f575","💂":"1f482","👷":"1f477","🤴":"1f934","👸":"1f478","👳":"1f473","👲":"1f472","🧕":"1f9d5","🧔":"1f9d4","👱":"1f471","🤵":"1f935","👰":"1f470","🤰":"1f930","🤱":"1f931","👼":"1f47c","🎅":"1f385","🤶":"1f936","🧙":"1f9d9","🧚":"1f9da","🧛":"1f9db","🧜":"1f9dc","🧝":"1f9dd","🧞":"1f9de","🧟":"1f9df","🙍":"1f64d","🙎":"1f64e","🙅":"1f645","🙆":"1f646","💁":"1f481","🙋":"1f64b","🙇":"1f647","🤦":"1f926","🤷":"1f937","💆":"1f486","💇":"1f487","🚶":"1f6b6","🏃":"1f3c3","💃":"1f483","🕺":"1f57a","👯":"1f46f","🧖":"1f9d6","🧗":"1f9d7","🧘":"1f9d8","🛀":"1f6c0","🛌":"1f6cc","🕴":"1f574","🗣":"1f5e3","👤":"1f464","👥":"1f465","🤺":"1f93a","🏇":"1f3c7","⛷":"26f7","🏂":"1f3c2","🏌":"1f3cc","🏄":"1f3c4","🚣":"1f6a3","🏊":"1f3ca","⛹":"26f9","🏋":"1f3cb","🚴":"1f6b4","🚵":"1f6b5","🏎":"1f3ce","🏍":"1f3cd","🤸":"1f938","🤼":"1f93c","🤽":"1f93d","🤾":"1f93e","🤹":"1f939","👫":"1f46b","👬":"1f46c","👭":"1f46d","💏":"1f48f","💑":"1f491","👪":"1f46a","🤳":"1f933","💪":"1f4aa","👈":"1f448","👉":"1f449","☝":"261d","👆":"1f446","🖕":"1f595","👇":"1f447","✌":"270c","🤞":"1f91e","🖖":"1f596","🤘":"1f918","🤙":"1f919","🖐":"1f590","✋":"270b","👌":"1f44c","👍":"1f44d","👎":"1f44e","✊":"270a","👊":"1f44a","🤛":"1f91b","🤜":"1f91c","🤚":"1f91a","👋":"1f44b","🤟":"1f91f","✍":"270d","👏":"1f44f","👐":"1f450","🙌":"1f64c","🤲":"1f932","🙏":"1f64f","🤝":"1f91d","💅":"1f485","👂":"1f442","👃":"1f443","👣":"1f463","👀":"1f440","👁":"1f441","🧠":"1f9e0","👅":"1f445","👄":"1f444","💋":"1f48b","💘":"1f498","❤":"2764","💓":"1f493","💔":"1f494","💕":"1f495","💖":"1f496","💗":"1f497","💙":"1f499","💚":"1f49a","💛":"1f49b","🧡":"1f9e1","💜":"1f49c","🖤":"1f5a4","💝":"1f49d","💞":"1f49e","💟":"1f49f","❣":"2763","💌":"1f48c","💤":"1f4a4","💢":"1f4a2","💣":"1f4a3","💥":"1f4a5","💦":"1f4a6","💨":"1f4a8","💫":"1f4ab","💬":"1f4ac","🗨":"1f5e8","🗯":"1f5ef","💭":"1f4ad","🕳":"1f573","👓":"1f453","🕶":"1f576","👔":"1f454","👕":"1f455","👖":"1f456","🧣":"1f9e3","🧤":"1f9e4","🧥":"1f9e5","🧦":"1f9e6","👗":"1f457","👘":"1f458","👙":"1f459","👚":"1f45a","👛":"1f45b","👜":"1f45c","👝":"1f45d","🛍":"1f6cd","🎒":"1f392","👞":"1f45e","👟":"1f45f","👠":"1f460","👡":"1f461","👢":"1f462","👑":"1f451","👒":"1f452","🎩":"1f3a9","🎓":"1f393","🧢":"1f9e2","⛑":"26d1","📿":"1f4ff","💄":"1f484","💍":"1f48d","💎":"1f48e","🐵":"1f435","🐒":"1f412","🦍":"1f98d","🐶":"1f436","🐕":"1f415","🐩":"1f429","🐺":"1f43a","🦊":"1f98a","🐱":"1f431","🐈":"1f408","🦁":"1f981","🐯":"1f42f","🐅":"1f405","🐆":"1f406","🐴":"1f434","🐎":"1f40e","🦄":"1f984","🦓":"1f993","🦌":"1f98c","🐮":"1f42e","🐂":"1f402","🐃":"1f403","🐄":"1f404","🐷":"1f437","🐖":"1f416","🐗":"1f417","🐽":"1f43d","🐏":"1f40f","🐑":"1f411","🐐":"1f410","🐪":"1f42a","🐫":"1f42b","🦒":"1f992","🐘":"1f418","🦏":"1f98f","🐭":"1f42d","🐁":"1f401","🐀":"1f400","🐹":"1f439","🐰":"1f430","🐇":"1f407","🐿":"1f43f","🦔":"1f994","🦇":"1f987","🐻":"1f43b","🐨":"1f428","🐼":"1f43c","🐾":"1f43e","🦃":"1f983","🐔":"1f414","🐓":"1f413","🐣":"1f423","🐤":"1f424","🐥":"1f425","🐦":"1f426","🐧":"1f427","🕊":"1f54a","🦅":"1f985","🦆":"1f986","🦉":"1f989","🐸":"1f438","🐊":"1f40a","🐢":"1f422","🦎":"1f98e","🐍":"1f40d","🐲":"1f432","🐉":"1f409","🦕":"1f995","🦖":"1f996","🐳":"1f433","🐋":"1f40b","🐬":"1f42c","🐟":"1f41f","🐠":"1f420","🐡":"1f421","🦈":"1f988","🐙":"1f419","🐚":"1f41a","🦀":"1f980","🦐":"1f990","🦑":"1f991","🐌":"1f40c","🦋":"1f98b","🐛":"1f41b","🐜":"1f41c","🐝":"1f41d","🐞":"1f41e","🦗":"1f997","🕷":"1f577","🕸":"1f578","🦂":"1f982","💐":"1f490","🌸":"1f338","💮":"1f4ae","🏵":"1f3f5","🌹":"1f339","🥀":"1f940","🌺":"1f33a","🌻":"1f33b","🌼":"1f33c","🌷":"1f337","🌱":"1f331","🌲":"1f332","🌳":"1f333","🌴":"1f334","🌵":"1f335","🌾":"1f33e","🌿":"1f33f","☘":"2618","🍀":"1f340","🍁":"1f341","🍂":"1f342","🍃":"1f343","🍇":"1f347","🍈":"1f348","🍉":"1f349","🍊":"1f34a","🍋":"1f34b","🍌":"1f34c","🍍":"1f34d","🍎":"1f34e","🍏":"1f34f","🍐":"1f350","🍑":"1f351","🍒":"1f352","🍓":"1f353","🥝":"1f95d","🍅":"1f345","🥥":"1f965","🥑":"1f951","🍆":"1f346","🥔":"1f954","🥕":"1f955","🌽":"1f33d","🌶":"1f336","🥒":"1f952","🥦":"1f966","🍄":"1f344","🥜":"1f95c","🌰":"1f330","🍞":"1f35e","🥐":"1f950","🥖":"1f956","🥨":"1f968","🥞":"1f95e","🧀":"1f9c0","🍖":"1f356","🍗":"1f357","🥩":"1f969","🥓":"1f953","🍔":"1f354","🍟":"1f35f","🍕":"1f355","🌭":"1f32d","🥪":"1f96a","🌮":"1f32e","🌯":"1f32f","🥙":"1f959","🥚":"1f95a","🍳":"1f373","🥘":"1f958","🍲":"1f372","🥣":"1f963","🥗":"1f957","🍿":"1f37f","🥫":"1f96b","🍱":"1f371","🍘":"1f358","🍙":"1f359","🍚":"1f35a","🍛":"1f35b","🍜":"1f35c","🍝":"1f35d","🍠":"1f360","🍢":"1f362","🍣":"1f363","🍤":"1f364","🍥":"1f365","🍡":"1f361","🥟":"1f95f","🥠":"1f960","🥡":"1f961","🍦":"1f366","🍧":"1f367","🍨":"1f368","🍩":"1f369","🍪":"1f36a","🎂":"1f382","🍰":"1f370","🥧":"1f967","🍫":"1f36b","🍬":"1f36c","🍭":"1f36d","🍮":"1f36e","🍯":"1f36f","🍼":"1f37c","🥛":"1f95b","☕":"2615","🍵":"1f375","🍶":"1f376","🍾":"1f37e","🍷":"1f377","🍸":"1f378","🍹":"1f379","🍺":"1f37a","🍻":"1f37b","🥂":"1f942","🥃":"1f943","🥤":"1f964","🥢":"1f962","🍽":"1f37d","🍴":"1f374","🥄":"1f944","🔪":"1f52a","🏺":"1f3fa","🌍":"1f30d","🌎":"1f30e","🌏":"1f30f","🌐":"1f310","🗺":"1f5fa","🗾":"1f5fe","🏔":"1f3d4","⛰":"26f0","🌋":"1f30b","🗻":"1f5fb","🏕":"1f3d5","🏖":"1f3d6","🏜":"1f3dc","🏝":"1f3dd","🏞":"1f3de","🏟":"1f3df","🏛":"1f3db","🏗":"1f3d7","🏘":"1f3d8","🏙":"1f3d9","🏚":"1f3da","🏠":"1f3e0","🏡":"1f3e1","🏢":"1f3e2","🏣":"1f3e3","🏤":"1f3e4","🏥":"1f3e5","🏦":"1f3e6","🏨":"1f3e8","🏩":"1f3e9","🏪":"1f3ea","🏫":"1f3eb","🏬":"1f3ec","🏭":"1f3ed","🏯":"1f3ef","🏰":"1f3f0","💒":"1f492","🗼":"1f5fc","🗽":"1f5fd","⛪":"26ea","🕌":"1f54c","🕍":"1f54d","⛩":"26e9","🕋":"1f54b","⛲":"26f2","⛺":"26fa","🌁":"1f301","🌃":"1f303","🌄":"1f304","🌅":"1f305","🌆":"1f306","🌇":"1f307","🌉":"1f309","♨":"2668","🌌":"1f30c","🎠":"1f3a0","🎡":"1f3a1","🎢":"1f3a2","💈":"1f488","🎪":"1f3aa","🎭":"1f3ad","🖼":"1f5bc","🎨":"1f3a8","🎰":"1f3b0","🚂":"1f682","🚃":"1f683","🚄":"1f684","🚅":"1f685","🚆":"1f686","🚇":"1f687","🚈":"1f688","🚉":"1f689","🚊":"1f68a","🚝":"1f69d","🚞":"1f69e","🚋":"1f68b","🚌":"1f68c","🚍":"1f68d","🚎":"1f68e","🚐":"1f690","🚑":"1f691","🚒":"1f692","🚓":"1f693","🚔":"1f694","🚕":"1f695","🚖":"1f696","🚗":"1f697","🚘":"1f698","🚙":"1f699","🚚":"1f69a","🚛":"1f69b","🚜":"1f69c","🚲":"1f6b2","🛴":"1f6f4","🛵":"1f6f5","🚏":"1f68f","🛣":"1f6e3","🛤":"1f6e4","⛽":"26fd","🚨":"1f6a8","🚥":"1f6a5","🚦":"1f6a6","🚧":"1f6a7","🛑":"1f6d1","⚓":"2693","⛵":"26f5","🛶":"1f6f6","🚤":"1f6a4","🛳":"1f6f3","⛴":"26f4","🛥":"1f6e5","🚢":"1f6a2","✈":"2708","🛩":"1f6e9","🛫":"1f6eb","🛬":"1f6ec","💺":"1f4ba","🚁":"1f681","🚟":"1f69f","🚠":"1f6a0","🚡":"1f6a1","🛰":"1f6f0","🚀":"1f680","🛸":"1f6f8","🛎":"1f6ce","🚪":"1f6aa","🛏":"1f6cf","🛋":"1f6cb","🚽":"1f6bd","🚿":"1f6bf","🛁":"1f6c1","⌛":"231b","⏳":"23f3","⌚":"231a","⏰":"23f0","⏱":"23f1","⏲":"23f2","🕰":"1f570","🕛":"1f55b","🕧":"1f567","🕐":"1f550","🕜":"1f55c","🕑":"1f551","🕝":"1f55d","🕒":"1f552","🕞":"1f55e","🕓":"1f553","🕟":"1f55f","🕔":"1f554","🕠":"1f560","🕕":"1f555","🕡":"1f561","🕖":"1f556","🕢":"1f562","🕗":"1f557","🕣":"1f563","🕘":"1f558","🕤":"1f564","🕙":"1f559","🕥":"1f565","🕚":"1f55a","🕦":"1f566","🌑":"1f311","🌒":"1f312","🌓":"1f313","🌔":"1f314","🌕":"1f315","🌖":"1f316","🌗":"1f317","🌘":"1f318","🌙":"1f319","🌚":"1f31a","🌛":"1f31b","🌜":"1f31c","🌡":"1f321","☀":"2600","🌝":"1f31d","🌞":"1f31e","⭐":"2b50","🌟":"1f31f","🌠":"1f320","☁":"2601","⛅":"26c5","⛈":"26c8","🌤":"1f324","🌥":"1f325","🌦":"1f326","🌧":"1f327","🌨":"1f328","🌩":"1f329","🌪":"1f32a","🌫":"1f32b","🌬":"1f32c","🌀":"1f300","🌈":"1f308","🌂":"1f302","☂":"2602","☔":"2614","⛱":"26f1","⚡":"26a1","❄":"2744","☃":"2603","⛄":"26c4","☄":"2604","🔥":"1f525","💧":"1f4a7","🌊":"1f30a","🎃":"1f383","🎄":"1f384","🎆":"1f386","🎇":"1f387","✨":"2728","🎈":"1f388","🎉":"1f389","🎊":"1f38a","🎋":"1f38b","🎍":"1f38d","🎎":"1f38e","🎏":"1f38f","🎐":"1f390","🎑":"1f391","🎀":"1f380","🎁":"1f381","🎗":"1f397","🎟":"1f39f","🎫":"1f3ab","🎖":"1f396","🏆":"1f3c6","🏅":"1f3c5","🥇":"1f947","🥈":"1f948","🥉":"1f949","⚽":"26bd","⚾":"26be","🏀":"1f3c0","🏐":"1f3d0","🏈":"1f3c8","🏉":"1f3c9","🎾":"1f3be","🎱":"1f3b1","🎳":"1f3b3","🏏":"1f3cf","🏑":"1f3d1","🏒":"1f3d2","🏓":"1f3d3","🏸":"1f3f8","🥊":"1f94a","🥋":"1f94b","🥅":"1f945","🎯":"1f3af","⛳":"26f3","⛸":"26f8","🎣":"1f3a3","🎽":"1f3bd","🎿":"1f3bf","🛷":"1f6f7","🥌":"1f94c","🎮":"1f3ae","🕹":"1f579","🎲":"1f3b2","♠":"2660","♥":"2665","♦":"2666","♣":"2663","🃏":"1f0cf","🀄":"1f004","🎴":"1f3b4","🔇":"1f507","🔈":"1f508","🔉":"1f509","🔊":"1f50a","📢":"1f4e2","📣":"1f4e3","📯":"1f4ef","🔔":"1f514","🔕":"1f515","🎼":"1f3bc","🎵":"1f3b5","🎶":"1f3b6","🎙":"1f399","🎚":"1f39a","🎛":"1f39b","🎤":"1f3a4","🎧":"1f3a7","📻":"1f4fb","🎷":"1f3b7","🎸":"1f3b8","🎹":"1f3b9","🎺":"1f3ba","🎻":"1f3bb","🥁":"1f941","📱":"1f4f1","📲":"1f4f2","☎":"260e","📞":"1f4de","📟":"1f4df","📠":"1f4e0","🔋":"1f50b","🔌":"1f50c","💻":"1f4bb","🖥":"1f5a5","🖨":"1f5a8","⌨":"2328","🖱":"1f5b1","🖲":"1f5b2","💽":"1f4bd","💾":"1f4be","💿":"1f4bf","📀":"1f4c0","🎥":"1f3a5","🎞":"1f39e","📽":"1f4fd","🎬":"1f3ac","📺":"1f4fa","📷":"1f4f7","📸":"1f4f8","📹":"1f4f9","📼":"1f4fc","🔍":"1f50d","🔎":"1f50e","🔬":"1f52c","🔭":"1f52d","📡":"1f4e1","🕯":"1f56f","💡":"1f4a1","🔦":"1f526","🏮":"1f3ee","📔":"1f4d4","📕":"1f4d5","📖":"1f4d6","📗":"1f4d7","📘":"1f4d8","📙":"1f4d9","📚":"1f4da","📓":"1f4d3","📒":"1f4d2","📃":"1f4c3","📜":"1f4dc","📄":"1f4c4","📰":"1f4f0","🗞":"1f5de","📑":"1f4d1","🔖":"1f516","🏷":"1f3f7","💰":"1f4b0","💴":"1f4b4","💵":"1f4b5","💶":"1f4b6","💷":"1f4b7","💸":"1f4b8","💳":"1f4b3","💹":"1f4b9","💱":"1f4b1","💲":"1f4b2","✉":"2709","📧":"1f4e7","📨":"1f4e8","📩":"1f4e9","📤":"1f4e4","📥":"1f4e5","📦":"1f4e6","📫":"1f4eb","📪":"1f4ea","📬":"1f4ec","📭":"1f4ed","📮":"1f4ee","🗳":"1f5f3","✏":"270f","✒":"2712","🖋":"1f58b","🖊":"1f58a","🖌":"1f58c","🖍":"1f58d","📝":"1f4dd","💼":"1f4bc","📁":"1f4c1","📂":"1f4c2","🗂":"1f5c2","📅":"1f4c5","📆":"1f4c6","🗒":"1f5d2","🗓":"1f5d3","📇":"1f4c7","📈":"1f4c8","📉":"1f4c9","📊":"1f4ca","📋":"1f4cb","📌":"1f4cc","📍":"1f4cd","📎":"1f4ce","🖇":"1f587","📏":"1f4cf","📐":"1f4d0","✂":"2702","🗃":"1f5c3","🗄":"1f5c4","🗑":"1f5d1","🔒":"1f512","🔓":"1f513","🔏":"1f50f","🔐":"1f510","🔑":"1f511","🗝":"1f5dd","🔨":"1f528","⛏":"26cf","⚒":"2692","🛠":"1f6e0","🗡":"1f5e1","⚔":"2694","🔫":"1f52b","🏹":"1f3f9","🛡":"1f6e1","🔧":"1f527","🔩":"1f529","⚙":"2699","🗜":"1f5dc","⚗":"2697","⚖":"2696","🔗":"1f517","⛓":"26d3","💉":"1f489","💊":"1f48a","🚬":"1f6ac","⚰":"26b0","⚱":"26b1","🗿":"1f5ff","🛢":"1f6e2","🔮":"1f52e","🛒":"1f6d2","🏧":"1f3e7","🚮":"1f6ae","🚰":"1f6b0","♿":"267f","🚹":"1f6b9","🚺":"1f6ba","🚻":"1f6bb","🚼":"1f6bc","🚾":"1f6be","🛂":"1f6c2","🛃":"1f6c3","🛄":"1f6c4","🛅":"1f6c5","⚠":"26a0","🚸":"1f6b8","⛔":"26d4","🚫":"1f6ab","🚳":"1f6b3","🚭":"1f6ad","🚯":"1f6af","🚱":"1f6b1","🚷":"1f6b7","📵":"1f4f5","🔞":"1f51e","☢":"2622","☣":"2623","⬆":"2b06","↗":"2197","➡":"27a1","↘":"2198","⬇":"2b07","↙":"2199","⬅":"2b05","↖":"2196","↕":"2195","↔":"2194","↩":"21a9","↪":"21aa","⤴":"2934","⤵":"2935","🔃":"1f503","🔄":"1f504","🔙":"1f519","🔚":"1f51a","🔛":"1f51b","🔜":"1f51c","🔝":"1f51d","🛐":"1f6d0","⚛":"269b","🕉":"1f549","✡":"2721","☸":"2638","☯":"262f","✝":"271d","☦":"2626","☪":"262a","☮":"262e","🕎":"1f54e","🔯":"1f52f","♈":"2648","♉":"2649","♊":"264a","♋":"264b","♌":"264c","♍":"264d","♎":"264e","♏":"264f","♐":"2650","♑":"2651","♒":"2652","♓":"2653","⛎":"26ce","🔀":"1f500","🔁":"1f501","🔂":"1f502","▶":"25b6","⏩":"23e9","⏭":"23ed","⏯":"23ef","◀":"25c0","⏪":"23ea","⏮":"23ee","🔼":"1f53c","⏫":"23eb","🔽":"1f53d","⏬":"23ec","⏸":"23f8","⏹":"23f9","⏺":"23fa","⏏":"23cf","🎦":"1f3a6","🔅":"1f505","🔆":"1f506","📶":"1f4f6","📳":"1f4f3","📴":"1f4f4","♀":"2640","♂":"2642","⚕":"2695","♻":"267b","⚜":"269c","🔱":"1f531","📛":"1f4db","🔰":"1f530","⭕":"2b55","✅":"2705","☑":"2611","✔":"2714","✖":"2716","❌":"274c","❎":"274e","➕":"2795","➖":"2796","➗":"2797","➰":"27b0","➿":"27bf","〽":"303d","✳":"2733","✴":"2734","❇":"2747","‼":"203c","⁉":"2049","❓":"2753","❔":"2754","❕":"2755","❗":"2757","〰":"3030","©":"a9","®":"ae","™":"2122","🔟":"1f51f","💯":"1f4af","🔠":"1f520","🔡":"1f521","🔢":"1f522","🔣":"1f523","🔤":"1f524","🅰":"1f170","🆎":"1f18e","🅱":"1f171","🆑":"1f191","🆒":"1f192","🆓":"1f193","ℹ":"2139","🆔":"1f194","Ⓜ":"24c2","🆕":"1f195","🆖":"1f196","🅾":"1f17e","🆗":"1f197","🅿":"1f17f","🆘":"1f198","🆙":"1f199","🆚":"1f19a","🈁":"1f201","🈂":"1f202","🈷":"1f237","🈶":"1f236","🈯":"1f22f","🉐":"1f250","🈹":"1f239","🈚":"1f21a","🈲":"1f232","🉑":"1f251","🈸":"1f238","🈴":"1f234","🈳":"1f233","㊗":"3297","㊙":"3299","🈺":"1f23a","🈵":"1f235","▪":"25aa","▫":"25ab","◻":"25fb","◼":"25fc","◽":"25fd","◾":"25fe","⬛":"2b1b","⬜":"2b1c","🔶":"1f536","🔷":"1f537","🔸":"1f538","🔹":"1f539","🔺":"1f53a","🔻":"1f53b","💠":"1f4a0","🔘":"1f518","🔲":"1f532","🔳":"1f533","⚪":"26aa","⚫":"26ab","🔴":"1f534","🔵":"1f535","🏁":"1f3c1","🚩":"1f6a9","🎌":"1f38c","🏴":"1f3f4","🏳":"1f3f3","☺️":"263a","☹️":"2639","☠️":"2620","👶🏻":"1f476-1f3fb","👶🏼":"1f476-1f3fc","👶🏽":"1f476-1f3fd","👶🏾":"1f476-1f3fe","👶🏿":"1f476-1f3ff","🧒🏻":"1f9d2-1f3fb","🧒🏼":"1f9d2-1f3fc","🧒🏽":"1f9d2-1f3fd","🧒🏾":"1f9d2-1f3fe","🧒🏿":"1f9d2-1f3ff","👦🏻":"1f466-1f3fb","👦🏼":"1f466-1f3fc","👦🏽":"1f466-1f3fd","👦🏾":"1f466-1f3fe","👦🏿":"1f466-1f3ff","👧🏻":"1f467-1f3fb","👧🏼":"1f467-1f3fc","👧🏽":"1f467-1f3fd","👧🏾":"1f467-1f3fe","👧🏿":"1f467-1f3ff","🧑🏻":"1f9d1-1f3fb","🧑🏼":"1f9d1-1f3fc","🧑🏽":"1f9d1-1f3fd","🧑🏾":"1f9d1-1f3fe","🧑🏿":"1f9d1-1f3ff","👨🏻":"1f468-1f3fb","👨🏼":"1f468-1f3fc","👨🏽":"1f468-1f3fd","👨🏾":"1f468-1f3fe","👨🏿":"1f468-1f3ff","👩🏻":"1f469-1f3fb","👩🏼":"1f469-1f3fc","👩🏽":"1f469-1f3fd","👩🏾":"1f469-1f3fe","👩🏿":"1f469-1f3ff","🧓🏻":"1f9d3-1f3fb","🧓🏼":"1f9d3-1f3fc","🧓🏽":"1f9d3-1f3fd","🧓🏾":"1f9d3-1f3fe","🧓🏿":"1f9d3-1f3ff","👴🏻":"1f474-1f3fb","👴🏼":"1f474-1f3fc","👴🏽":"1f474-1f3fd","👴🏾":"1f474-1f3fe","👴🏿":"1f474-1f3ff","👵🏻":"1f475-1f3fb","👵🏼":"1f475-1f3fc","👵🏽":"1f475-1f3fd","👵🏾":"1f475-1f3fe","👵🏿":"1f475-1f3ff","👮🏻":"1f46e-1f3fb","👮🏼":"1f46e-1f3fc","👮🏽":"1f46e-1f3fd","👮🏾":"1f46e-1f3fe","👮🏿":"1f46e-1f3ff","🕵️":"1f575","🕵🏻":"1f575-1f3fb","🕵🏼":"1f575-1f3fc","🕵🏽":"1f575-1f3fd","🕵🏾":"1f575-1f3fe","🕵🏿":"1f575-1f3ff","💂🏻":"1f482-1f3fb","💂🏼":"1f482-1f3fc","💂🏽":"1f482-1f3fd","💂🏾":"1f482-1f3fe","💂🏿":"1f482-1f3ff","👷🏻":"1f477-1f3fb","👷🏼":"1f477-1f3fc","👷🏽":"1f477-1f3fd","👷🏾":"1f477-1f3fe","👷🏿":"1f477-1f3ff","🤴🏻":"1f934-1f3fb","🤴🏼":"1f934-1f3fc","🤴🏽":"1f934-1f3fd","🤴🏾":"1f934-1f3fe","🤴🏿":"1f934-1f3ff","👸🏻":"1f478-1f3fb","👸🏼":"1f478-1f3fc","👸🏽":"1f478-1f3fd","👸🏾":"1f478-1f3fe","👸🏿":"1f478-1f3ff","👳🏻":"1f473-1f3fb","👳🏼":"1f473-1f3fc","👳🏽":"1f473-1f3fd","👳🏾":"1f473-1f3fe","👳🏿":"1f473-1f3ff","👲🏻":"1f472-1f3fb","👲🏼":"1f472-1f3fc","👲🏽":"1f472-1f3fd","👲🏾":"1f472-1f3fe","👲🏿":"1f472-1f3ff","🧕🏻":"1f9d5-1f3fb","🧕🏼":"1f9d5-1f3fc","🧕🏽":"1f9d5-1f3fd","🧕🏾":"1f9d5-1f3fe","🧕🏿":"1f9d5-1f3ff","🧔🏻":"1f9d4-1f3fb","🧔🏼":"1f9d4-1f3fc","🧔🏽":"1f9d4-1f3fd","🧔🏾":"1f9d4-1f3fe","🧔🏿":"1f9d4-1f3ff","👱🏻":"1f471-1f3fb","👱🏼":"1f471-1f3fc","👱🏽":"1f471-1f3fd","👱🏾":"1f471-1f3fe","👱🏿":"1f471-1f3ff","🤵🏻":"1f935-1f3fb","🤵🏼":"1f935-1f3fc","🤵🏽":"1f935-1f3fd","🤵🏾":"1f935-1f3fe","🤵🏿":"1f935-1f3ff","👰🏻":"1f470-1f3fb","👰🏼":"1f470-1f3fc","👰🏽":"1f470-1f3fd","👰🏾":"1f470-1f3fe","👰🏿":"1f470-1f3ff","🤰🏻":"1f930-1f3fb","🤰🏼":"1f930-1f3fc","🤰🏽":"1f930-1f3fd","🤰🏾":"1f930-1f3fe","🤰🏿":"1f930-1f3ff","🤱🏻":"1f931-1f3fb","🤱🏼":"1f931-1f3fc","🤱🏽":"1f931-1f3fd","🤱🏾":"1f931-1f3fe","🤱🏿":"1f931-1f3ff","👼🏻":"1f47c-1f3fb","👼🏼":"1f47c-1f3fc","👼🏽":"1f47c-1f3fd","👼🏾":"1f47c-1f3fe","👼🏿":"1f47c-1f3ff","🎅🏻":"1f385-1f3fb","🎅🏼":"1f385-1f3fc","🎅🏽":"1f385-1f3fd","🎅🏾":"1f385-1f3fe","🎅🏿":"1f385-1f3ff","🤶🏻":"1f936-1f3fb","🤶🏼":"1f936-1f3fc","🤶🏽":"1f936-1f3fd","🤶🏾":"1f936-1f3fe","🤶🏿":"1f936-1f3ff","🧙🏻":"1f9d9-1f3fb","🧙🏼":"1f9d9-1f3fc","🧙🏽":"1f9d9-1f3fd","🧙🏾":"1f9d9-1f3fe","🧙🏿":"1f9d9-1f3ff","🧚🏻":"1f9da-1f3fb","🧚🏼":"1f9da-1f3fc","🧚🏽":"1f9da-1f3fd","🧚🏾":"1f9da-1f3fe","🧚🏿":"1f9da-1f3ff","🧛🏻":"1f9db-1f3fb","🧛🏼":"1f9db-1f3fc","🧛🏽":"1f9db-1f3fd","🧛🏾":"1f9db-1f3fe","🧛🏿":"1f9db-1f3ff","🧜🏻":"1f9dc-1f3fb","🧜🏼":"1f9dc-1f3fc","🧜🏽":"1f9dc-1f3fd","🧜🏾":"1f9dc-1f3fe","🧜🏿":"1f9dc-1f3ff","🧝🏻":"1f9dd-1f3fb","🧝🏼":"1f9dd-1f3fc","🧝🏽":"1f9dd-1f3fd","🧝🏾":"1f9dd-1f3fe","🧝🏿":"1f9dd-1f3ff","🙍🏻":"1f64d-1f3fb","🙍🏼":"1f64d-1f3fc","🙍🏽":"1f64d-1f3fd","🙍🏾":"1f64d-1f3fe","🙍🏿":"1f64d-1f3ff","🙎🏻":"1f64e-1f3fb","🙎🏼":"1f64e-1f3fc","🙎🏽":"1f64e-1f3fd","🙎🏾":"1f64e-1f3fe","🙎🏿":"1f64e-1f3ff","🙅🏻":"1f645-1f3fb","🙅🏼":"1f645-1f3fc","🙅🏽":"1f645-1f3fd","🙅🏾":"1f645-1f3fe","🙅🏿":"1f645-1f3ff","🙆🏻":"1f646-1f3fb","🙆🏼":"1f646-1f3fc","🙆🏽":"1f646-1f3fd","🙆🏾":"1f646-1f3fe","🙆🏿":"1f646-1f3ff","💁🏻":"1f481-1f3fb","💁🏼":"1f481-1f3fc","💁🏽":"1f481-1f3fd","💁🏾":"1f481-1f3fe","💁🏿":"1f481-1f3ff","🙋🏻":"1f64b-1f3fb","🙋🏼":"1f64b-1f3fc","🙋🏽":"1f64b-1f3fd","🙋🏾":"1f64b-1f3fe","🙋🏿":"1f64b-1f3ff","🙇🏻":"1f647-1f3fb","🙇🏼":"1f647-1f3fc","🙇🏽":"1f647-1f3fd","🙇🏾":"1f647-1f3fe","🙇🏿":"1f647-1f3ff","🤦🏻":"1f926-1f3fb","🤦🏼":"1f926-1f3fc","🤦🏽":"1f926-1f3fd","🤦🏾":"1f926-1f3fe","🤦🏿":"1f926-1f3ff","🤷🏻":"1f937-1f3fb","🤷🏼":"1f937-1f3fc","🤷🏽":"1f937-1f3fd","🤷🏾":"1f937-1f3fe","🤷🏿":"1f937-1f3ff","💆🏻":"1f486-1f3fb","💆🏼":"1f486-1f3fc","💆🏽":"1f486-1f3fd","💆🏾":"1f486-1f3fe","💆🏿":"1f486-1f3ff","💇🏻":"1f487-1f3fb","💇🏼":"1f487-1f3fc","💇🏽":"1f487-1f3fd","💇🏾":"1f487-1f3fe","💇🏿":"1f487-1f3ff","🚶🏻":"1f6b6-1f3fb","🚶🏼":"1f6b6-1f3fc","🚶🏽":"1f6b6-1f3fd","🚶🏾":"1f6b6-1f3fe","🚶🏿":"1f6b6-1f3ff","🏃🏻":"1f3c3-1f3fb","🏃🏼":"1f3c3-1f3fc","🏃🏽":"1f3c3-1f3fd","🏃🏾":"1f3c3-1f3fe","🏃🏿":"1f3c3-1f3ff","💃🏻":"1f483-1f3fb","💃🏼":"1f483-1f3fc","💃🏽":"1f483-1f3fd","💃🏾":"1f483-1f3fe","💃🏿":"1f483-1f3ff","🕺🏻":"1f57a-1f3fb","🕺🏼":"1f57a-1f3fc","🕺🏽":"1f57a-1f3fd","🕺🏾":"1f57a-1f3fe","🕺🏿":"1f57a-1f3ff","🧖🏻":"1f9d6-1f3fb","🧖🏼":"1f9d6-1f3fc","🧖🏽":"1f9d6-1f3fd","🧖🏾":"1f9d6-1f3fe","🧖🏿":"1f9d6-1f3ff","🧗🏻":"1f9d7-1f3fb","🧗🏼":"1f9d7-1f3fc","🧗🏽":"1f9d7-1f3fd","🧗🏾":"1f9d7-1f3fe","🧗🏿":"1f9d7-1f3ff","🧘🏻":"1f9d8-1f3fb","🧘🏼":"1f9d8-1f3fc","🧘🏽":"1f9d8-1f3fd","🧘🏾":"1f9d8-1f3fe","🧘🏿":"1f9d8-1f3ff","🛀🏻":"1f6c0-1f3fb","🛀🏼":"1f6c0-1f3fc","🛀🏽":"1f6c0-1f3fd","🛀🏾":"1f6c0-1f3fe","🛀🏿":"1f6c0-1f3ff","🛌🏻":"1f6cc-1f3fb","🛌🏼":"1f6cc-1f3fc","🛌🏽":"1f6cc-1f3fd","🛌🏾":"1f6cc-1f3fe","🛌🏿":"1f6cc-1f3ff","🕴️":"1f574","🕴🏻":"1f574-1f3fb","🕴🏼":"1f574-1f3fc","🕴🏽":"1f574-1f3fd","🕴🏾":"1f574-1f3fe","🕴🏿":"1f574-1f3ff","🗣️":"1f5e3","🏇🏻":"1f3c7-1f3fb","🏇🏼":"1f3c7-1f3fc","🏇🏽":"1f3c7-1f3fd","🏇🏾":"1f3c7-1f3fe","🏇🏿":"1f3c7-1f3ff","⛷️":"26f7","🏂🏻":"1f3c2-1f3fb","🏂🏼":"1f3c2-1f3fc","🏂🏽":"1f3c2-1f3fd","🏂🏾":"1f3c2-1f3fe","🏂🏿":"1f3c2-1f3ff","🏌️":"1f3cc","🏌🏻":"1f3cc-1f3fb","🏌🏼":"1f3cc-1f3fc","🏌🏽":"1f3cc-1f3fd","🏌🏾":"1f3cc-1f3fe","🏌🏿":"1f3cc-1f3ff","🏄🏻":"1f3c4-1f3fb","🏄🏼":"1f3c4-1f3fc","🏄🏽":"1f3c4-1f3fd","🏄🏾":"1f3c4-1f3fe","🏄🏿":"1f3c4-1f3ff","🚣🏻":"1f6a3-1f3fb","🚣🏼":"1f6a3-1f3fc","🚣🏽":"1f6a3-1f3fd","🚣🏾":"1f6a3-1f3fe","🚣🏿":"1f6a3-1f3ff","🏊🏻":"1f3ca-1f3fb","🏊🏼":"1f3ca-1f3fc","🏊🏽":"1f3ca-1f3fd","🏊🏾":"1f3ca-1f3fe","🏊🏿":"1f3ca-1f3ff","⛹️":"26f9","⛹🏻":"26f9-1f3fb","⛹🏼":"26f9-1f3fc","⛹🏽":"26f9-1f3fd","⛹🏾":"26f9-1f3fe","⛹🏿":"26f9-1f3ff","🏋️":"1f3cb","🏋🏻":"1f3cb-1f3fb","🏋🏼":"1f3cb-1f3fc","🏋🏽":"1f3cb-1f3fd","🏋🏾":"1f3cb-1f3fe","🏋🏿":"1f3cb-1f3ff","🚴🏻":"1f6b4-1f3fb","🚴🏼":"1f6b4-1f3fc","🚴🏽":"1f6b4-1f3fd","🚴🏾":"1f6b4-1f3fe","🚴🏿":"1f6b4-1f3ff","🚵🏻":"1f6b5-1f3fb","🚵🏼":"1f6b5-1f3fc","🚵🏽":"1f6b5-1f3fd","🚵🏾":"1f6b5-1f3fe","🚵🏿":"1f6b5-1f3ff","🏎️":"1f3ce","🏍️":"1f3cd","🤸🏻":"1f938-1f3fb","🤸🏼":"1f938-1f3fc","🤸🏽":"1f938-1f3fd","🤸🏾":"1f938-1f3fe","🤸🏿":"1f938-1f3ff","🤽🏻":"1f93d-1f3fb","🤽🏼":"1f93d-1f3fc","🤽🏽":"1f93d-1f3fd","🤽🏾":"1f93d-1f3fe","🤽🏿":"1f93d-1f3ff","🤾🏻":"1f93e-1f3fb","🤾🏼":"1f93e-1f3fc","🤾🏽":"1f93e-1f3fd","🤾🏾":"1f93e-1f3fe","🤾🏿":"1f93e-1f3ff","🤹🏻":"1f939-1f3fb","🤹🏼":"1f939-1f3fc","🤹🏽":"1f939-1f3fd","🤹🏾":"1f939-1f3fe","🤹🏿":"1f939-1f3ff","🤳🏻":"1f933-1f3fb","🤳🏼":"1f933-1f3fc","🤳🏽":"1f933-1f3fd","🤳🏾":"1f933-1f3fe","🤳🏿":"1f933-1f3ff","💪🏻":"1f4aa-1f3fb","💪🏼":"1f4aa-1f3fc","💪🏽":"1f4aa-1f3fd","💪🏾":"1f4aa-1f3fe","💪🏿":"1f4aa-1f3ff","👈🏻":"1f448-1f3fb","👈🏼":"1f448-1f3fc","👈🏽":"1f448-1f3fd","👈🏾":"1f448-1f3fe","👈🏿":"1f448-1f3ff","👉🏻":"1f449-1f3fb","👉🏼":"1f449-1f3fc","👉🏽":"1f449-1f3fd","👉🏾":"1f449-1f3fe","👉🏿":"1f449-1f3ff","☝️":"261d","☝🏻":"261d-1f3fb","☝🏼":"261d-1f3fc","☝🏽":"261d-1f3fd","☝🏾":"261d-1f3fe","☝🏿":"261d-1f3ff","👆🏻":"1f446-1f3fb","👆🏼":"1f446-1f3fc","👆🏽":"1f446-1f3fd","👆🏾":"1f446-1f3fe","👆🏿":"1f446-1f3ff","🖕🏻":"1f595-1f3fb","🖕🏼":"1f595-1f3fc","🖕🏽":"1f595-1f3fd","🖕🏾":"1f595-1f3fe","🖕🏿":"1f595-1f3ff","👇🏻":"1f447-1f3fb","👇🏼":"1f447-1f3fc","👇🏽":"1f447-1f3fd","👇🏾":"1f447-1f3fe","👇🏿":"1f447-1f3ff","✌️":"270c","✌🏻":"270c-1f3fb","✌🏼":"270c-1f3fc","✌🏽":"270c-1f3fd","✌🏾":"270c-1f3fe","✌🏿":"270c-1f3ff","🤞🏻":"1f91e-1f3fb","🤞🏼":"1f91e-1f3fc","🤞🏽":"1f91e-1f3fd","🤞🏾":"1f91e-1f3fe","🤞🏿":"1f91e-1f3ff","🖖🏻":"1f596-1f3fb","🖖🏼":"1f596-1f3fc","🖖🏽":"1f596-1f3fd","🖖🏾":"1f596-1f3fe","🖖🏿":"1f596-1f3ff","🤘🏻":"1f918-1f3fb","🤘🏼":"1f918-1f3fc","🤘🏽":"1f918-1f3fd","🤘🏾":"1f918-1f3fe","🤘🏿":"1f918-1f3ff","🤙🏻":"1f919-1f3fb","🤙🏼":"1f919-1f3fc","🤙🏽":"1f919-1f3fd","🤙🏾":"1f919-1f3fe","🤙🏿":"1f919-1f3ff","🖐️":"1f590","🖐🏻":"1f590-1f3fb","🖐🏼":"1f590-1f3fc","🖐🏽":"1f590-1f3fd","🖐🏾":"1f590-1f3fe","🖐🏿":"1f590-1f3ff","✋🏻":"270b-1f3fb","✋🏼":"270b-1f3fc","✋🏽":"270b-1f3fd","✋🏾":"270b-1f3fe","✋🏿":"270b-1f3ff","👌🏻":"1f44c-1f3fb","👌🏼":"1f44c-1f3fc","👌🏽":"1f44c-1f3fd","👌🏾":"1f44c-1f3fe","👌🏿":"1f44c-1f3ff","👍🏻":"1f44d-1f3fb","👍🏼":"1f44d-1f3fc","👍🏽":"1f44d-1f3fd","👍🏾":"1f44d-1f3fe","👍🏿":"1f44d-1f3ff","👎🏻":"1f44e-1f3fb","👎🏼":"1f44e-1f3fc","👎🏽":"1f44e-1f3fd","👎🏾":"1f44e-1f3fe","👎🏿":"1f44e-1f3ff","✊🏻":"270a-1f3fb","✊🏼":"270a-1f3fc","✊🏽":"270a-1f3fd","✊🏾":"270a-1f3fe","✊🏿":"270a-1f3ff","👊🏻":"1f44a-1f3fb","👊🏼":"1f44a-1f3fc","👊🏽":"1f44a-1f3fd","👊🏾":"1f44a-1f3fe","👊🏿":"1f44a-1f3ff","🤛🏻":"1f91b-1f3fb","🤛🏼":"1f91b-1f3fc","🤛🏽":"1f91b-1f3fd","🤛🏾":"1f91b-1f3fe","🤛🏿":"1f91b-1f3ff","🤜🏻":"1f91c-1f3fb","🤜🏼":"1f91c-1f3fc","🤜🏽":"1f91c-1f3fd","🤜🏾":"1f91c-1f3fe","🤜🏿":"1f91c-1f3ff","🤚🏻":"1f91a-1f3fb","🤚🏼":"1f91a-1f3fc","🤚🏽":"1f91a-1f3fd","🤚🏾":"1f91a-1f3fe","🤚🏿":"1f91a-1f3ff","👋🏻":"1f44b-1f3fb","👋🏼":"1f44b-1f3fc","👋🏽":"1f44b-1f3fd","👋🏾":"1f44b-1f3fe","👋🏿":"1f44b-1f3ff","🤟🏻":"1f91f-1f3fb","🤟🏼":"1f91f-1f3fc","🤟🏽":"1f91f-1f3fd","🤟🏾":"1f91f-1f3fe","🤟🏿":"1f91f-1f3ff","✍️":"270d","✍🏻":"270d-1f3fb","✍🏼":"270d-1f3fc","✍🏽":"270d-1f3fd","✍🏾":"270d-1f3fe","✍🏿":"270d-1f3ff","👏🏻":"1f44f-1f3fb","👏🏼":"1f44f-1f3fc","👏🏽":"1f44f-1f3fd","👏🏾":"1f44f-1f3fe","👏🏿":"1f44f-1f3ff","👐🏻":"1f450-1f3fb","👐🏼":"1f450-1f3fc","👐🏽":"1f450-1f3fd","👐🏾":"1f450-1f3fe","👐🏿":"1f450-1f3ff","🙌🏻":"1f64c-1f3fb","🙌🏼":"1f64c-1f3fc","🙌🏽":"1f64c-1f3fd","🙌🏾":"1f64c-1f3fe","🙌🏿":"1f64c-1f3ff","🤲🏻":"1f932-1f3fb","🤲🏼":"1f932-1f3fc","🤲🏽":"1f932-1f3fd","🤲🏾":"1f932-1f3fe","🤲🏿":"1f932-1f3ff","🙏🏻":"1f64f-1f3fb","🙏🏼":"1f64f-1f3fc","🙏🏽":"1f64f-1f3fd","🙏🏾":"1f64f-1f3fe","🙏🏿":"1f64f-1f3ff","💅🏻":"1f485-1f3fb","💅🏼":"1f485-1f3fc","💅🏽":"1f485-1f3fd","💅🏾":"1f485-1f3fe","💅🏿":"1f485-1f3ff","👂🏻":"1f442-1f3fb","👂🏼":"1f442-1f3fc","👂🏽":"1f442-1f3fd","👂🏾":"1f442-1f3fe","👂🏿":"1f442-1f3ff","👃🏻":"1f443-1f3fb","👃🏼":"1f443-1f3fc","👃🏽":"1f443-1f3fd","👃🏾":"1f443-1f3fe","👃🏿":"1f443-1f3ff","👁️":"1f441","❤️":"2764","❣️":"2763","🗨️":"1f5e8","🗯️":"1f5ef","🕳️":"1f573","🕶️":"1f576","🛍️":"1f6cd","⛑️":"26d1","🐿️":"1f43f","🕊️":"1f54a","🕷️":"1f577","🕸️":"1f578","🏵️":"1f3f5","☘️":"2618","🌶️":"1f336","🍽️":"1f37d","🗺️":"1f5fa","🏔️":"1f3d4","⛰️":"26f0","🏕️":"1f3d5","🏖️":"1f3d6","🏜️":"1f3dc","🏝️":"1f3dd","🏞️":"1f3de","🏟️":"1f3df","🏛️":"1f3db","🏗️":"1f3d7","🏘️":"1f3d8","🏙️":"1f3d9","🏚️":"1f3da","⛩️":"26e9","♨️":"2668","🖼️":"1f5bc","🛣️":"1f6e3","🛤️":"1f6e4","🛳️":"1f6f3","⛴️":"26f4","🛥️":"1f6e5","✈️":"2708","🛩️":"1f6e9","🛰️":"1f6f0","🛎️":"1f6ce","🛏️":"1f6cf","🛋️":"1f6cb","⏱️":"23f1","⏲️":"23f2","🕰️":"1f570","🌡️":"1f321","☀️":"2600","☁️":"2601","⛈️":"26c8","🌤️":"1f324","🌥️":"1f325","🌦️":"1f326","🌧️":"1f327","🌨️":"1f328","🌩️":"1f329","🌪️":"1f32a","🌫️":"1f32b","🌬️":"1f32c","☂️":"2602","⛱️":"26f1","❄️":"2744","☃️":"2603","☄️":"2604","🎗️":"1f397","🎟️":"1f39f","🎖️":"1f396","⛸️":"26f8","🕹️":"1f579","♠️":"2660","♥️":"2665","♦️":"2666","♣️":"2663","🎙️":"1f399","🎚️":"1f39a","🎛️":"1f39b","☎️":"260e","🖥️":"1f5a5","🖨️":"1f5a8","⌨️":"2328","🖱️":"1f5b1","🖲️":"1f5b2","🎞️":"1f39e","📽️":"1f4fd","🕯️":"1f56f","🗞️":"1f5de","🏷️":"1f3f7","✉️":"2709","🗳️":"1f5f3","✏️":"270f","✒️":"2712","🖋️":"1f58b","🖊️":"1f58a","🖌️":"1f58c","🖍️":"1f58d","🗂️":"1f5c2","🗒️":"1f5d2","🗓️":"1f5d3","🖇️":"1f587","✂️":"2702","🗃️":"1f5c3","🗄️":"1f5c4","🗑️":"1f5d1","🗝️":"1f5dd","⛏️":"26cf","⚒️":"2692","🛠️":"1f6e0","🗡️":"1f5e1","⚔️":"2694","🛡️":"1f6e1","⚙️":"2699","🗜️":"1f5dc","⚗️":"2697","⚖️":"2696","⛓️":"26d3","⚰️":"26b0","⚱️":"26b1","🛢️":"1f6e2","⚠️":"26a0","☢️":"2622","☣️":"2623","⬆️":"2b06","↗️":"2197","➡️":"27a1","↘️":"2198","⬇️":"2b07","↙️":"2199","⬅️":"2b05","↖️":"2196","↕️":"2195","↔️":"2194","↩️":"21a9","↪️":"21aa","⤴️":"2934","⤵️":"2935","⚛️":"269b","🕉️":"1f549","✡️":"2721","☸️":"2638","☯️":"262f","✝️":"271d","☦️":"2626","☪️":"262a","☮️":"262e","▶️":"25b6","⏭️":"23ed","⏯️":"23ef","◀️":"25c0","⏮️":"23ee","⏸️":"23f8","⏹️":"23f9","⏺️":"23fa","⏏️":"23cf","♀️":"2640","♂️":"2642","⚕️":"2695","♻️":"267b","⚜️":"269c","☑️":"2611","✔️":"2714","✖️":"2716","〽️":"303d","✳️":"2733","✴️":"2734","❇️":"2747","‼️":"203c","⁉️":"2049","〰️":"3030","©️":"a9","®️":"ae","™️":"2122","#⃣":"23-20e3","*⃣":"2a-20e3","0⃣":"30-20e3","1⃣":"31-20e3","2⃣":"32-20e3","3⃣":"33-20e3","4⃣":"34-20e3","5⃣":"35-20e3","6⃣":"36-20e3","7⃣":"37-20e3","8⃣":"38-20e3","9⃣":"39-20e3","🅰️":"1f170","🅱️":"1f171","ℹ️":"2139","Ⓜ️":"24c2","🅾️":"1f17e","🅿️":"1f17f","🈂️":"1f202","🈷️":"1f237","㊗️":"3297","㊙️":"3299","▪️":"25aa","▫️":"25ab","◻️":"25fb","◼️":"25fc","🏳️":"1f3f3","🇦🇨":"1f1e6-1f1e8","🇦🇩":"1f1e6-1f1e9","🇦🇪":"1f1e6-1f1ea","🇦🇫":"1f1e6-1f1eb","🇦🇬":"1f1e6-1f1ec","🇦🇮":"1f1e6-1f1ee","🇦🇱":"1f1e6-1f1f1","🇦🇲":"1f1e6-1f1f2","🇦🇴":"1f1e6-1f1f4","🇦🇶":"1f1e6-1f1f6","🇦🇷":"1f1e6-1f1f7","🇦🇸":"1f1e6-1f1f8","🇦🇹":"1f1e6-1f1f9","🇦🇺":"1f1e6-1f1fa","🇦🇼":"1f1e6-1f1fc","🇦🇽":"1f1e6-1f1fd","🇦🇿":"1f1e6-1f1ff","🇧🇦":"1f1e7-1f1e6","🇧🇧":"1f1e7-1f1e7","🇧🇩":"1f1e7-1f1e9","🇧🇪":"1f1e7-1f1ea","🇧🇫":"1f1e7-1f1eb","🇧🇬":"1f1e7-1f1ec","🇧🇭":"1f1e7-1f1ed","🇧🇮":"1f1e7-1f1ee","🇧🇯":"1f1e7-1f1ef","🇧🇱":"1f1e7-1f1f1","🇧🇲":"1f1e7-1f1f2","🇧🇳":"1f1e7-1f1f3","🇧🇴":"1f1e7-1f1f4","🇧🇶":"1f1e7-1f1f6","🇧🇷":"1f1e7-1f1f7","🇧🇸":"1f1e7-1f1f8","🇧🇹":"1f1e7-1f1f9","🇧🇻":"1f1e7-1f1fb","🇧🇼":"1f1e7-1f1fc","🇧🇾":"1f1e7-1f1fe","🇧🇿":"1f1e7-1f1ff","🇨🇦":"1f1e8-1f1e6","🇨🇨":"1f1e8-1f1e8","🇨🇩":"1f1e8-1f1e9","🇨🇫":"1f1e8-1f1eb","🇨🇬":"1f1e8-1f1ec","🇨🇭":"1f1e8-1f1ed","🇨🇮":"1f1e8-1f1ee","🇨🇰":"1f1e8-1f1f0","🇨🇱":"1f1e8-1f1f1","🇨🇲":"1f1e8-1f1f2","🇨🇳":"1f1e8-1f1f3","🇨🇴":"1f1e8-1f1f4","🇨🇵":"1f1e8-1f1f5","🇨🇷":"1f1e8-1f1f7","🇨🇺":"1f1e8-1f1fa","🇨🇻":"1f1e8-1f1fb","🇨🇼":"1f1e8-1f1fc","🇨🇽":"1f1e8-1f1fd","🇨🇾":"1f1e8-1f1fe","🇨🇿":"1f1e8-1f1ff","🇩🇪":"1f1e9-1f1ea","🇩🇬":"1f1e9-1f1ec","🇩🇯":"1f1e9-1f1ef","🇩🇰":"1f1e9-1f1f0","🇩🇲":"1f1e9-1f1f2","🇩🇴":"1f1e9-1f1f4","🇩🇿":"1f1e9-1f1ff","🇪🇦":"1f1ea-1f1e6","🇪🇨":"1f1ea-1f1e8","🇪🇪":"1f1ea-1f1ea","🇪🇬":"1f1ea-1f1ec","🇪🇭":"1f1ea-1f1ed","🇪🇷":"1f1ea-1f1f7","🇪🇸":"1f1ea-1f1f8","🇪🇹":"1f1ea-1f1f9","🇪🇺":"1f1ea-1f1fa","🇫🇮":"1f1eb-1f1ee","🇫🇯":"1f1eb-1f1ef","🇫🇰":"1f1eb-1f1f0","🇫🇲":"1f1eb-1f1f2","🇫🇴":"1f1eb-1f1f4","🇫🇷":"1f1eb-1f1f7","🇬🇦":"1f1ec-1f1e6","🇬🇧":"1f1ec-1f1e7","🇬🇩":"1f1ec-1f1e9","🇬🇪":"1f1ec-1f1ea","🇬🇫":"1f1ec-1f1eb","🇬🇬":"1f1ec-1f1ec","🇬🇭":"1f1ec-1f1ed","🇬🇮":"1f1ec-1f1ee","🇬🇱":"1f1ec-1f1f1","🇬🇲":"1f1ec-1f1f2","🇬🇳":"1f1ec-1f1f3","🇬🇵":"1f1ec-1f1f5","🇬🇶":"1f1ec-1f1f6","🇬🇷":"1f1ec-1f1f7","🇬🇸":"1f1ec-1f1f8","🇬🇹":"1f1ec-1f1f9","🇬🇺":"1f1ec-1f1fa","🇬🇼":"1f1ec-1f1fc","🇬🇾":"1f1ec-1f1fe","🇭🇰":"1f1ed-1f1f0","🇭🇲":"1f1ed-1f1f2","🇭🇳":"1f1ed-1f1f3","🇭🇷":"1f1ed-1f1f7","🇭🇹":"1f1ed-1f1f9","🇭🇺":"1f1ed-1f1fa","🇮🇨":"1f1ee-1f1e8","🇮🇩":"1f1ee-1f1e9","🇮🇪":"1f1ee-1f1ea","🇮🇱":"1f1ee-1f1f1","🇮🇲":"1f1ee-1f1f2","🇮🇳":"1f1ee-1f1f3","🇮🇴":"1f1ee-1f1f4","🇮🇶":"1f1ee-1f1f6","🇮🇷":"1f1ee-1f1f7","🇮🇸":"1f1ee-1f1f8","🇮🇹":"1f1ee-1f1f9","🇯🇪":"1f1ef-1f1ea","🇯🇲":"1f1ef-1f1f2","🇯🇴":"1f1ef-1f1f4","🇯🇵":"1f1ef-1f1f5","🇰🇪":"1f1f0-1f1ea","🇰🇬":"1f1f0-1f1ec","🇰🇭":"1f1f0-1f1ed","🇰🇮":"1f1f0-1f1ee","🇰🇲":"1f1f0-1f1f2","🇰🇳":"1f1f0-1f1f3","🇰🇵":"1f1f0-1f1f5","🇰🇷":"1f1f0-1f1f7","🇰🇼":"1f1f0-1f1fc","🇰🇾":"1f1f0-1f1fe","🇰🇿":"1f1f0-1f1ff","🇱🇦":"1f1f1-1f1e6","🇱🇧":"1f1f1-1f1e7","🇱🇨":"1f1f1-1f1e8","🇱🇮":"1f1f1-1f1ee","🇱🇰":"1f1f1-1f1f0","🇱🇷":"1f1f1-1f1f7","🇱🇸":"1f1f1-1f1f8","🇱🇹":"1f1f1-1f1f9","🇱🇺":"1f1f1-1f1fa","🇱🇻":"1f1f1-1f1fb","🇱🇾":"1f1f1-1f1fe","🇲🇦":"1f1f2-1f1e6","🇲🇨":"1f1f2-1f1e8","🇲🇩":"1f1f2-1f1e9","🇲🇪":"1f1f2-1f1ea","🇲🇫":"1f1f2-1f1eb","🇲🇬":"1f1f2-1f1ec","🇲🇭":"1f1f2-1f1ed","🇲🇰":"1f1f2-1f1f0","🇲🇱":"1f1f2-1f1f1","🇲🇲":"1f1f2-1f1f2","🇲🇳":"1f1f2-1f1f3","🇲🇴":"1f1f2-1f1f4","🇲🇵":"1f1f2-1f1f5","🇲🇶":"1f1f2-1f1f6","🇲🇷":"1f1f2-1f1f7","🇲🇸":"1f1f2-1f1f8","🇲🇹":"1f1f2-1f1f9","🇲🇺":"1f1f2-1f1fa","🇲🇻":"1f1f2-1f1fb","🇲🇼":"1f1f2-1f1fc","🇲🇽":"1f1f2-1f1fd","🇲🇾":"1f1f2-1f1fe","🇲🇿":"1f1f2-1f1ff","🇳🇦":"1f1f3-1f1e6","🇳🇨":"1f1f3-1f1e8","🇳🇪":"1f1f3-1f1ea","🇳🇫":"1f1f3-1f1eb","🇳🇬":"1f1f3-1f1ec","🇳🇮":"1f1f3-1f1ee","🇳🇱":"1f1f3-1f1f1","🇳🇴":"1f1f3-1f1f4","🇳🇵":"1f1f3-1f1f5","🇳🇷":"1f1f3-1f1f7","🇳🇺":"1f1f3-1f1fa","🇳🇿":"1f1f3-1f1ff","🇴🇲":"1f1f4-1f1f2","🇵🇦":"1f1f5-1f1e6","🇵🇪":"1f1f5-1f1ea","🇵🇫":"1f1f5-1f1eb","🇵🇬":"1f1f5-1f1ec","🇵🇭":"1f1f5-1f1ed","🇵🇰":"1f1f5-1f1f0","🇵🇱":"1f1f5-1f1f1","🇵🇲":"1f1f5-1f1f2","🇵🇳":"1f1f5-1f1f3","🇵🇷":"1f1f5-1f1f7","🇵🇸":"1f1f5-1f1f8","🇵🇹":"1f1f5-1f1f9","🇵🇼":"1f1f5-1f1fc","🇵🇾":"1f1f5-1f1fe","🇶🇦":"1f1f6-1f1e6","🇷🇪":"1f1f7-1f1ea","🇷🇴":"1f1f7-1f1f4","🇷🇸":"1f1f7-1f1f8","🇷🇺":"1f1f7-1f1fa","🇷🇼":"1f1f7-1f1fc","🇸🇦":"1f1f8-1f1e6","🇸🇧":"1f1f8-1f1e7","🇸🇨":"1f1f8-1f1e8","🇸🇩":"1f1f8-1f1e9","🇸🇪":"1f1f8-1f1ea","🇸🇬":"1f1f8-1f1ec","🇸🇭":"1f1f8-1f1ed","🇸🇮":"1f1f8-1f1ee","🇸🇯":"1f1f8-1f1ef","🇸🇰":"1f1f8-1f1f0","🇸🇱":"1f1f8-1f1f1","🇸🇲":"1f1f8-1f1f2","🇸🇳":"1f1f8-1f1f3","🇸🇴":"1f1f8-1f1f4","🇸🇷":"1f1f8-1f1f7","🇸🇸":"1f1f8-1f1f8","🇸🇹":"1f1f8-1f1f9","🇸🇻":"1f1f8-1f1fb","🇸🇽":"1f1f8-1f1fd","🇸🇾":"1f1f8-1f1fe","🇸🇿":"1f1f8-1f1ff","🇹🇦":"1f1f9-1f1e6","🇹🇨":"1f1f9-1f1e8","🇹🇩":"1f1f9-1f1e9","🇹🇫":"1f1f9-1f1eb","🇹🇬":"1f1f9-1f1ec","🇹🇭":"1f1f9-1f1ed","🇹🇯":"1f1f9-1f1ef","🇹🇰":"1f1f9-1f1f0","🇹🇱":"1f1f9-1f1f1","🇹🇲":"1f1f9-1f1f2","🇹🇳":"1f1f9-1f1f3","🇹🇴":"1f1f9-1f1f4","🇹🇷":"1f1f9-1f1f7","🇹🇹":"1f1f9-1f1f9","🇹🇻":"1f1f9-1f1fb","🇹🇼":"1f1f9-1f1fc","🇹🇿":"1f1f9-1f1ff","🇺🇦":"1f1fa-1f1e6","🇺🇬":"1f1fa-1f1ec","🇺🇲":"1f1fa-1f1f2","🇺🇳":"1f1fa-1f1f3","🇺🇸":"1f1fa-1f1f8","🇺🇾":"1f1fa-1f1fe","🇺🇿":"1f1fa-1f1ff","🇻🇦":"1f1fb-1f1e6","🇻🇨":"1f1fb-1f1e8","🇻🇪":"1f1fb-1f1ea","🇻🇬":"1f1fb-1f1ec","🇻🇮":"1f1fb-1f1ee","🇻🇳":"1f1fb-1f1f3","🇻🇺":"1f1fb-1f1fa","🇼🇫":"1f1fc-1f1eb","🇼🇸":"1f1fc-1f1f8","🇽🇰":"1f1fd-1f1f0","🇾🇪":"1f1fe-1f1ea","🇾🇹":"1f1fe-1f1f9","🇿🇦":"1f1ff-1f1e6","🇿🇲":"1f1ff-1f1f2","🇿🇼":"1f1ff-1f1fc","👨‍⚕":"1f468-200d-2695-fe0f","👩‍⚕":"1f469-200d-2695-fe0f","👨‍🎓":"1f468-200d-1f393","👩‍🎓":"1f469-200d-1f393","👨‍🏫":"1f468-200d-1f3eb","👩‍🏫":"1f469-200d-1f3eb","👨‍⚖":"1f468-200d-2696-fe0f","👩‍⚖":"1f469-200d-2696-fe0f","👨‍🌾":"1f468-200d-1f33e","👩‍🌾":"1f469-200d-1f33e","👨‍🍳":"1f468-200d-1f373","👩‍🍳":"1f469-200d-1f373","👨‍🔧":"1f468-200d-1f527","👩‍🔧":"1f469-200d-1f527","👨‍🏭":"1f468-200d-1f3ed","👩‍🏭":"1f469-200d-1f3ed","👨‍💼":"1f468-200d-1f4bc","👩‍💼":"1f469-200d-1f4bc","👨‍🔬":"1f468-200d-1f52c","👩‍🔬":"1f469-200d-1f52c","👨‍💻":"1f468-200d-1f4bb","👩‍💻":"1f469-200d-1f4bb","👨‍🎤":"1f468-200d-1f3a4","👩‍🎤":"1f469-200d-1f3a4","👨‍🎨":"1f468-200d-1f3a8","👩‍🎨":"1f469-200d-1f3a8","👨‍✈":"1f468-200d-2708-fe0f","👩‍✈":"1f469-200d-2708-fe0f","👨‍🚀":"1f468-200d-1f680","👩‍🚀":"1f469-200d-1f680","👨‍🚒":"1f468-200d-1f692","👩‍🚒":"1f469-200d-1f692","👮‍♂":"1f46e-200d-2642-fe0f","👮‍♀":"1f46e-200d-2640-fe0f","🕵‍♂":"1f575-fe0f-200d-2642-fe0f","🕵‍♀":"1f575-fe0f-200d-2640-fe0f","💂‍♂":"1f482-200d-2642-fe0f","💂‍♀":"1f482-200d-2640-fe0f","👷‍♂":"1f477-200d-2642-fe0f","👷‍♀":"1f477-200d-2640-fe0f","👳‍♂":"1f473-200d-2642-fe0f","👳‍♀":"1f473-200d-2640-fe0f","👱‍♂":"1f471-200d-2642-fe0f","👱‍♀":"1f471-200d-2640-fe0f","🧙‍♀":"1f9d9-200d-2640-fe0f","🧙‍♂":"1f9d9-200d-2642-fe0f","🧚‍♀":"1f9da-200d-2640-fe0f","🧚‍♂":"1f9da-200d-2642-fe0f","🧛‍♀":"1f9db-200d-2640-fe0f","🧛‍♂":"1f9db-200d-2642-fe0f","🧜‍♀":"1f9dc-200d-2640-fe0f","🧜‍♂":"1f9dc-200d-2642-fe0f","🧝‍♀":"1f9dd-200d-2640-fe0f","🧝‍♂":"1f9dd-200d-2642-fe0f","🧞‍♀":"1f9de-200d-2640-fe0f","🧞‍♂":"1f9de-200d-2642-fe0f","🧟‍♀":"1f9df-200d-2640-fe0f","🧟‍♂":"1f9df-200d-2642-fe0f","🙍‍♂":"1f64d-200d-2642-fe0f","🙍‍♀":"1f64d-200d-2640-fe0f","🙎‍♂":"1f64e-200d-2642-fe0f","🙎‍♀":"1f64e-200d-2640-fe0f","🙅‍♂":"1f645-200d-2642-fe0f","🙅‍♀":"1f645-200d-2640-fe0f","🙆‍♂":"1f646-200d-2642-fe0f","🙆‍♀":"1f646-200d-2640-fe0f","💁‍♂":"1f481-200d-2642-fe0f","💁‍♀":"1f481-200d-2640-fe0f","🙋‍♂":"1f64b-200d-2642-fe0f","🙋‍♀":"1f64b-200d-2640-fe0f","🙇‍♂":"1f647-200d-2642-fe0f","🙇‍♀":"1f647-200d-2640-fe0f","🤦‍♂":"1f926-200d-2642-fe0f","🤦‍♀":"1f926-200d-2640-fe0f","🤷‍♂":"1f937-200d-2642-fe0f","🤷‍♀":"1f937-200d-2640-fe0f","💆‍♂":"1f486-200d-2642-fe0f","💆‍♀":"1f486-200d-2640-fe0f","💇‍♂":"1f487-200d-2642-fe0f","💇‍♀":"1f487-200d-2640-fe0f","🚶‍♂":"1f6b6-200d-2642-fe0f","🚶‍♀":"1f6b6-200d-2640-fe0f","🏃‍♂":"1f3c3-200d-2642-fe0f","🏃‍♀":"1f3c3-200d-2640-fe0f","👯‍♂":"1f46f-200d-2642-fe0f","👯‍♀":"1f46f-200d-2640-fe0f","🧖‍♀":"1f9d6-200d-2640-fe0f","🧖‍♂":"1f9d6-200d-2642-fe0f","🧗‍♀":"1f9d7-200d-2640-fe0f","🧗‍♂":"1f9d7-200d-2642-fe0f","🧘‍♀":"1f9d8-200d-2640-fe0f","🧘‍♂":"1f9d8-200d-2642-fe0f","🏌‍♂":"1f3cc-fe0f-200d-2642-fe0f","🏌‍♀":"1f3cc-fe0f-200d-2640-fe0f","🏄‍♂":"1f3c4-200d-2642-fe0f","🏄‍♀":"1f3c4-200d-2640-fe0f","🚣‍♂":"1f6a3-200d-2642-fe0f","🚣‍♀":"1f6a3-200d-2640-fe0f","🏊‍♂":"1f3ca-200d-2642-fe0f","🏊‍♀":"1f3ca-200d-2640-fe0f","⛹‍♂":"26f9-fe0f-200d-2642-fe0f","⛹‍♀":"26f9-fe0f-200d-2640-fe0f","🏋‍♂":"1f3cb-fe0f-200d-2642-fe0f","🏋‍♀":"1f3cb-fe0f-200d-2640-fe0f","🚴‍♂":"1f6b4-200d-2642-fe0f","🚴‍♀":"1f6b4-200d-2640-fe0f","🚵‍♂":"1f6b5-200d-2642-fe0f","🚵‍♀":"1f6b5-200d-2640-fe0f","🤸‍♂":"1f938-200d-2642-fe0f","🤸‍♀":"1f938-200d-2640-fe0f","🤼‍♂":"1f93c-200d-2642-fe0f","🤼‍♀":"1f93c-200d-2640-fe0f","🤽‍♂":"1f93d-200d-2642-fe0f","🤽‍♀":"1f93d-200d-2640-fe0f","🤾‍♂":"1f93e-200d-2642-fe0f","🤾‍♀":"1f93e-200d-2640-fe0f","🤹‍♂":"1f939-200d-2642-fe0f","🤹‍♀":"1f939-200d-2640-fe0f","👨‍👦":"1f468-200d-1f466","👨‍👧":"1f468-200d-1f467","👩‍👦":"1f469-200d-1f466","👩‍👧":"1f469-200d-1f467","👁‍🗨":"1f441-200d-1f5e8","#️⃣":"23-20e3","*️⃣":"2a-20e3","0️⃣":"30-20e3","1️⃣":"31-20e3","2️⃣":"32-20e3","3️⃣":"33-20e3","4️⃣":"34-20e3","5️⃣":"35-20e3","6️⃣":"36-20e3","7️⃣":"37-20e3","8️⃣":"38-20e3","9️⃣":"39-20e3","🏳‍🌈":"1f3f3-fe0f-200d-1f308","👨‍⚕️":"1f468-200d-2695-fe0f","👨🏻‍⚕":"1f468-1f3fb-200d-2695-fe0f","👨🏼‍⚕":"1f468-1f3fc-200d-2695-fe0f","👨🏽‍⚕":"1f468-1f3fd-200d-2695-fe0f","👨🏾‍⚕":"1f468-1f3fe-200d-2695-fe0f","👨🏿‍⚕":"1f468-1f3ff-200d-2695-fe0f","👩‍⚕️":"1f469-200d-2695-fe0f","👩🏻‍⚕":"1f469-1f3fb-200d-2695-fe0f","👩🏼‍⚕":"1f469-1f3fc-200d-2695-fe0f","👩🏽‍⚕":"1f469-1f3fd-200d-2695-fe0f","👩🏾‍⚕":"1f469-1f3fe-200d-2695-fe0f","👩🏿‍⚕":"1f469-1f3ff-200d-2695-fe0f","👨🏻‍🎓":"1f468-1f3fb-200d-1f393","👨🏼‍🎓":"1f468-1f3fc-200d-1f393","👨🏽‍🎓":"1f468-1f3fd-200d-1f393","👨🏾‍🎓":"1f468-1f3fe-200d-1f393","👨🏿‍🎓":"1f468-1f3ff-200d-1f393","👩🏻‍🎓":"1f469-1f3fb-200d-1f393","👩🏼‍🎓":"1f469-1f3fc-200d-1f393","👩🏽‍🎓":"1f469-1f3fd-200d-1f393","👩🏾‍🎓":"1f469-1f3fe-200d-1f393","👩🏿‍🎓":"1f469-1f3ff-200d-1f393","👨🏻‍🏫":"1f468-1f3fb-200d-1f3eb","👨🏼‍🏫":"1f468-1f3fc-200d-1f3eb","👨🏽‍🏫":"1f468-1f3fd-200d-1f3eb","👨🏾‍🏫":"1f468-1f3fe-200d-1f3eb","👨🏿‍🏫":"1f468-1f3ff-200d-1f3eb","👩🏻‍🏫":"1f469-1f3fb-200d-1f3eb","👩🏼‍🏫":"1f469-1f3fc-200d-1f3eb","👩🏽‍🏫":"1f469-1f3fd-200d-1f3eb","👩🏾‍🏫":"1f469-1f3fe-200d-1f3eb","👩🏿‍🏫":"1f469-1f3ff-200d-1f3eb","👨‍⚖️":"1f468-200d-2696-fe0f","👨🏻‍⚖":"1f468-1f3fb-200d-2696-fe0f","👨🏼‍⚖":"1f468-1f3fc-200d-2696-fe0f","👨🏽‍⚖":"1f468-1f3fd-200d-2696-fe0f","👨🏾‍⚖":"1f468-1f3fe-200d-2696-fe0f","👨🏿‍⚖":"1f468-1f3ff-200d-2696-fe0f","👩‍⚖️":"1f469-200d-2696-fe0f","👩🏻‍⚖":"1f469-1f3fb-200d-2696-fe0f","👩🏼‍⚖":"1f469-1f3fc-200d-2696-fe0f","👩🏽‍⚖":"1f469-1f3fd-200d-2696-fe0f","👩🏾‍⚖":"1f469-1f3fe-200d-2696-fe0f","👩🏿‍⚖":"1f469-1f3ff-200d-2696-fe0f","👨🏻‍🌾":"1f468-1f3fb-200d-1f33e","👨🏼‍🌾":"1f468-1f3fc-200d-1f33e","👨🏽‍🌾":"1f468-1f3fd-200d-1f33e","👨🏾‍🌾":"1f468-1f3fe-200d-1f33e","👨🏿‍🌾":"1f468-1f3ff-200d-1f33e","👩🏻‍🌾":"1f469-1f3fb-200d-1f33e","👩🏼‍🌾":"1f469-1f3fc-200d-1f33e","👩🏽‍🌾":"1f469-1f3fd-200d-1f33e","👩🏾‍🌾":"1f469-1f3fe-200d-1f33e","👩🏿‍🌾":"1f469-1f3ff-200d-1f33e","👨🏻‍🍳":"1f468-1f3fb-200d-1f373","👨🏼‍🍳":"1f468-1f3fc-200d-1f373","👨🏽‍🍳":"1f468-1f3fd-200d-1f373","👨🏾‍🍳":"1f468-1f3fe-200d-1f373","👨🏿‍🍳":"1f468-1f3ff-200d-1f373","👩🏻‍🍳":"1f469-1f3fb-200d-1f373","👩🏼‍🍳":"1f469-1f3fc-200d-1f373","👩🏽‍🍳":"1f469-1f3fd-200d-1f373","👩🏾‍🍳":"1f469-1f3fe-200d-1f373","👩🏿‍🍳":"1f469-1f3ff-200d-1f373","👨🏻‍🔧":"1f468-1f3fb-200d-1f527","👨🏼‍🔧":"1f468-1f3fc-200d-1f527","👨🏽‍🔧":"1f468-1f3fd-200d-1f527","👨🏾‍🔧":"1f468-1f3fe-200d-1f527","👨🏿‍🔧":"1f468-1f3ff-200d-1f527","👩🏻‍🔧":"1f469-1f3fb-200d-1f527","👩🏼‍🔧":"1f469-1f3fc-200d-1f527","👩🏽‍🔧":"1f469-1f3fd-200d-1f527","👩🏾‍🔧":"1f469-1f3fe-200d-1f527","👩🏿‍🔧":"1f469-1f3ff-200d-1f527","👨🏻‍🏭":"1f468-1f3fb-200d-1f3ed","👨🏼‍🏭":"1f468-1f3fc-200d-1f3ed","👨🏽‍🏭":"1f468-1f3fd-200d-1f3ed","👨🏾‍🏭":"1f468-1f3fe-200d-1f3ed","👨🏿‍🏭":"1f468-1f3ff-200d-1f3ed","👩🏻‍🏭":"1f469-1f3fb-200d-1f3ed","👩🏼‍🏭":"1f469-1f3fc-200d-1f3ed","👩🏽‍🏭":"1f469-1f3fd-200d-1f3ed","👩🏾‍🏭":"1f469-1f3fe-200d-1f3ed","👩🏿‍🏭":"1f469-1f3ff-200d-1f3ed","👨🏻‍💼":"1f468-1f3fb-200d-1f4bc","👨🏼‍💼":"1f468-1f3fc-200d-1f4bc","👨🏽‍💼":"1f468-1f3fd-200d-1f4bc","👨🏾‍💼":"1f468-1f3fe-200d-1f4bc","👨🏿‍💼":"1f468-1f3ff-200d-1f4bc","👩🏻‍💼":"1f469-1f3fb-200d-1f4bc","👩🏼‍💼":"1f469-1f3fc-200d-1f4bc","👩🏽‍💼":"1f469-1f3fd-200d-1f4bc","👩🏾‍💼":"1f469-1f3fe-200d-1f4bc","👩🏿‍💼":"1f469-1f3ff-200d-1f4bc","👨🏻‍🔬":"1f468-1f3fb-200d-1f52c","👨🏼‍🔬":"1f468-1f3fc-200d-1f52c","👨🏽‍🔬":"1f468-1f3fd-200d-1f52c","👨🏾‍🔬":"1f468-1f3fe-200d-1f52c","👨🏿‍🔬":"1f468-1f3ff-200d-1f52c","👩🏻‍🔬":"1f469-1f3fb-200d-1f52c","👩🏼‍🔬":"1f469-1f3fc-200d-1f52c","👩🏽‍🔬":"1f469-1f3fd-200d-1f52c","👩🏾‍🔬":"1f469-1f3fe-200d-1f52c","👩🏿‍🔬":"1f469-1f3ff-200d-1f52c","👨🏻‍💻":"1f468-1f3fb-200d-1f4bb","👨🏼‍💻":"1f468-1f3fc-200d-1f4bb","👨🏽‍💻":"1f468-1f3fd-200d-1f4bb","👨🏾‍💻":"1f468-1f3fe-200d-1f4bb","👨🏿‍💻":"1f468-1f3ff-200d-1f4bb","👩🏻‍💻":"1f469-1f3fb-200d-1f4bb","👩🏼‍💻":"1f469-1f3fc-200d-1f4bb","👩🏽‍💻":"1f469-1f3fd-200d-1f4bb","👩🏾‍💻":"1f469-1f3fe-200d-1f4bb","👩🏿‍💻":"1f469-1f3ff-200d-1f4bb","👨🏻‍🎤":"1f468-1f3fb-200d-1f3a4","👨🏼‍🎤":"1f468-1f3fc-200d-1f3a4","👨🏽‍🎤":"1f468-1f3fd-200d-1f3a4","👨🏾‍🎤":"1f468-1f3fe-200d-1f3a4","👨🏿‍🎤":"1f468-1f3ff-200d-1f3a4","👩🏻‍🎤":"1f469-1f3fb-200d-1f3a4","👩🏼‍🎤":"1f469-1f3fc-200d-1f3a4","👩🏽‍🎤":"1f469-1f3fd-200d-1f3a4","👩🏾‍🎤":"1f469-1f3fe-200d-1f3a4","👩🏿‍🎤":"1f469-1f3ff-200d-1f3a4","👨🏻‍🎨":"1f468-1f3fb-200d-1f3a8","👨🏼‍🎨":"1f468-1f3fc-200d-1f3a8","👨🏽‍🎨":"1f468-1f3fd-200d-1f3a8","👨🏾‍🎨":"1f468-1f3fe-200d-1f3a8","👨🏿‍🎨":"1f468-1f3ff-200d-1f3a8","👩🏻‍🎨":"1f469-1f3fb-200d-1f3a8","👩🏼‍🎨":"1f469-1f3fc-200d-1f3a8","👩🏽‍🎨":"1f469-1f3fd-200d-1f3a8","👩🏾‍🎨":"1f469-1f3fe-200d-1f3a8","👩🏿‍🎨":"1f469-1f3ff-200d-1f3a8","👨‍✈️":"1f468-200d-2708-fe0f","👨🏻‍✈":"1f468-1f3fb-200d-2708-fe0f","👨🏼‍✈":"1f468-1f3fc-200d-2708-fe0f","👨🏽‍✈":"1f468-1f3fd-200d-2708-fe0f","👨🏾‍✈":"1f468-1f3fe-200d-2708-fe0f","👨🏿‍✈":"1f468-1f3ff-200d-2708-fe0f","👩‍✈️":"1f469-200d-2708-fe0f","👩🏻‍✈":"1f469-1f3fb-200d-2708-fe0f","👩🏼‍✈":"1f469-1f3fc-200d-2708-fe0f","👩🏽‍✈":"1f469-1f3fd-200d-2708-fe0f","👩🏾‍✈":"1f469-1f3fe-200d-2708-fe0f","👩🏿‍✈":"1f469-1f3ff-200d-2708-fe0f","👨🏻‍🚀":"1f468-1f3fb-200d-1f680","👨🏼‍🚀":"1f468-1f3fc-200d-1f680","👨🏽‍🚀":"1f468-1f3fd-200d-1f680","👨🏾‍🚀":"1f468-1f3fe-200d-1f680","👨🏿‍🚀":"1f468-1f3ff-200d-1f680","👩🏻‍🚀":"1f469-1f3fb-200d-1f680","👩🏼‍🚀":"1f469-1f3fc-200d-1f680","👩🏽‍🚀":"1f469-1f3fd-200d-1f680","👩🏾‍🚀":"1f469-1f3fe-200d-1f680","👩🏿‍🚀":"1f469-1f3ff-200d-1f680","👨🏻‍🚒":"1f468-1f3fb-200d-1f692","👨🏼‍🚒":"1f468-1f3fc-200d-1f692","👨🏽‍🚒":"1f468-1f3fd-200d-1f692","👨🏾‍🚒":"1f468-1f3fe-200d-1f692","👨🏿‍🚒":"1f468-1f3ff-200d-1f692","👩🏻‍🚒":"1f469-1f3fb-200d-1f692","👩🏼‍🚒":"1f469-1f3fc-200d-1f692","👩🏽‍🚒":"1f469-1f3fd-200d-1f692","👩🏾‍🚒":"1f469-1f3fe-200d-1f692","👩🏿‍🚒":"1f469-1f3ff-200d-1f692","👮‍♂️":"1f46e-200d-2642-fe0f","👮🏻‍♂":"1f46e-1f3fb-200d-2642-fe0f","👮🏼‍♂":"1f46e-1f3fc-200d-2642-fe0f","👮🏽‍♂":"1f46e-1f3fd-200d-2642-fe0f","👮🏾‍♂":"1f46e-1f3fe-200d-2642-fe0f","👮🏿‍♂":"1f46e-1f3ff-200d-2642-fe0f","👮‍♀️":"1f46e-200d-2640-fe0f","👮🏻‍♀":"1f46e-1f3fb-200d-2640-fe0f","👮🏼‍♀":"1f46e-1f3fc-200d-2640-fe0f","👮🏽‍♀":"1f46e-1f3fd-200d-2640-fe0f","👮🏾‍♀":"1f46e-1f3fe-200d-2640-fe0f","👮🏿‍♀":"1f46e-1f3ff-200d-2640-fe0f","🕵‍♂️":"1f575-fe0f-200d-2642-fe0f","🕵️‍♂":"1f575-fe0f-200d-2642-fe0f","🕵🏻‍♂":"1f575-1f3fb-200d-2642-fe0f","🕵🏼‍♂":"1f575-1f3fc-200d-2642-fe0f","🕵🏽‍♂":"1f575-1f3fd-200d-2642-fe0f","🕵🏾‍♂":"1f575-1f3fe-200d-2642-fe0f","🕵🏿‍♂":"1f575-1f3ff-200d-2642-fe0f","🕵‍♀️":"1f575-fe0f-200d-2640-fe0f","🕵️‍♀":"1f575-fe0f-200d-2640-fe0f","🕵🏻‍♀":"1f575-1f3fb-200d-2640-fe0f","🕵🏼‍♀":"1f575-1f3fc-200d-2640-fe0f","🕵🏽‍♀":"1f575-1f3fd-200d-2640-fe0f","🕵🏾‍♀":"1f575-1f3fe-200d-2640-fe0f","🕵🏿‍♀":"1f575-1f3ff-200d-2640-fe0f","💂‍♂️":"1f482-200d-2642-fe0f","💂🏻‍♂":"1f482-1f3fb-200d-2642-fe0f","💂🏼‍♂":"1f482-1f3fc-200d-2642-fe0f","💂🏽‍♂":"1f482-1f3fd-200d-2642-fe0f","💂🏾‍♂":"1f482-1f3fe-200d-2642-fe0f","💂🏿‍♂":"1f482-1f3ff-200d-2642-fe0f","💂‍♀️":"1f482-200d-2640-fe0f","💂🏻‍♀":"1f482-1f3fb-200d-2640-fe0f","💂🏼‍♀":"1f482-1f3fc-200d-2640-fe0f","💂🏽‍♀":"1f482-1f3fd-200d-2640-fe0f","💂🏾‍♀":"1f482-1f3fe-200d-2640-fe0f","💂🏿‍♀":"1f482-1f3ff-200d-2640-fe0f","👷‍♂️":"1f477-200d-2642-fe0f","👷🏻‍♂":"1f477-1f3fb-200d-2642-fe0f","👷🏼‍♂":"1f477-1f3fc-200d-2642-fe0f","👷🏽‍♂":"1f477-1f3fd-200d-2642-fe0f","👷🏾‍♂":"1f477-1f3fe-200d-2642-fe0f","👷🏿‍♂":"1f477-1f3ff-200d-2642-fe0f","👷‍♀️":"1f477-200d-2640-fe0f","👷🏻‍♀":"1f477-1f3fb-200d-2640-fe0f","👷🏼‍♀":"1f477-1f3fc-200d-2640-fe0f","👷🏽‍♀":"1f477-1f3fd-200d-2640-fe0f","👷🏾‍♀":"1f477-1f3fe-200d-2640-fe0f","👷🏿‍♀":"1f477-1f3ff-200d-2640-fe0f","👳‍♂️":"1f473-200d-2642-fe0f","👳🏻‍♂":"1f473-1f3fb-200d-2642-fe0f","👳🏼‍♂":"1f473-1f3fc-200d-2642-fe0f","👳🏽‍♂":"1f473-1f3fd-200d-2642-fe0f","👳🏾‍♂":"1f473-1f3fe-200d-2642-fe0f","👳🏿‍♂":"1f473-1f3ff-200d-2642-fe0f","👳‍♀️":"1f473-200d-2640-fe0f","👳🏻‍♀":"1f473-1f3fb-200d-2640-fe0f","👳🏼‍♀":"1f473-1f3fc-200d-2640-fe0f","👳🏽‍♀":"1f473-1f3fd-200d-2640-fe0f","👳🏾‍♀":"1f473-1f3fe-200d-2640-fe0f","👳🏿‍♀":"1f473-1f3ff-200d-2640-fe0f","👱‍♂️":"1f471-200d-2642-fe0f","👱🏻‍♂":"1f471-1f3fb-200d-2642-fe0f","👱🏼‍♂":"1f471-1f3fc-200d-2642-fe0f","👱🏽‍♂":"1f471-1f3fd-200d-2642-fe0f","👱🏾‍♂":"1f471-1f3fe-200d-2642-fe0f","👱🏿‍♂":"1f471-1f3ff-200d-2642-fe0f","👱‍♀️":"1f471-200d-2640-fe0f","👱🏻‍♀":"1f471-1f3fb-200d-2640-fe0f","👱🏼‍♀":"1f471-1f3fc-200d-2640-fe0f","👱🏽‍♀":"1f471-1f3fd-200d-2640-fe0f","👱🏾‍♀":"1f471-1f3fe-200d-2640-fe0f","👱🏿‍♀":"1f471-1f3ff-200d-2640-fe0f","🧙‍♀️":"1f9d9-200d-2640-fe0f","🧙🏻‍♀":"1f9d9-1f3fb-200d-2640-fe0f","🧙🏼‍♀":"1f9d9-1f3fc-200d-2640-fe0f","🧙🏽‍♀":"1f9d9-1f3fd-200d-2640-fe0f","🧙🏾‍♀":"1f9d9-1f3fe-200d-2640-fe0f","🧙🏿‍♀":"1f9d9-1f3ff-200d-2640-fe0f","🧙‍♂️":"1f9d9-200d-2642-fe0f","🧙🏻‍♂":"1f9d9-1f3fb-200d-2642-fe0f","🧙🏼‍♂":"1f9d9-1f3fc-200d-2642-fe0f","🧙🏽‍♂":"1f9d9-1f3fd-200d-2642-fe0f","🧙🏾‍♂":"1f9d9-1f3fe-200d-2642-fe0f","🧙🏿‍♂":"1f9d9-1f3ff-200d-2642-fe0f","🧚‍♀️":"1f9da-200d-2640-fe0f","🧚🏻‍♀":"1f9da-1f3fb-200d-2640-fe0f","🧚🏼‍♀":"1f9da-1f3fc-200d-2640-fe0f","🧚🏽‍♀":"1f9da-1f3fd-200d-2640-fe0f","🧚🏾‍♀":"1f9da-1f3fe-200d-2640-fe0f","🧚🏿‍♀":"1f9da-1f3ff-200d-2640-fe0f","🧚‍♂️":"1f9da-200d-2642-fe0f","🧚🏻‍♂":"1f9da-1f3fb-200d-2642-fe0f","🧚🏼‍♂":"1f9da-1f3fc-200d-2642-fe0f","🧚🏽‍♂":"1f9da-1f3fd-200d-2642-fe0f","🧚🏾‍♂":"1f9da-1f3fe-200d-2642-fe0f","🧚🏿‍♂":"1f9da-1f3ff-200d-2642-fe0f","🧛‍♀️":"1f9db-200d-2640-fe0f","🧛🏻‍♀":"1f9db-1f3fb-200d-2640-fe0f","🧛🏼‍♀":"1f9db-1f3fc-200d-2640-fe0f","🧛🏽‍♀":"1f9db-1f3fd-200d-2640-fe0f","🧛🏾‍♀":"1f9db-1f3fe-200d-2640-fe0f","🧛🏿‍♀":"1f9db-1f3ff-200d-2640-fe0f","🧛‍♂️":"1f9db-200d-2642-fe0f","🧛🏻‍♂":"1f9db-1f3fb-200d-2642-fe0f","🧛🏼‍♂":"1f9db-1f3fc-200d-2642-fe0f","🧛🏽‍♂":"1f9db-1f3fd-200d-2642-fe0f","🧛🏾‍♂":"1f9db-1f3fe-200d-2642-fe0f","🧛🏿‍♂":"1f9db-1f3ff-200d-2642-fe0f","🧜‍♀️":"1f9dc-200d-2640-fe0f","🧜🏻‍♀":"1f9dc-1f3fb-200d-2640-fe0f","🧜🏼‍♀":"1f9dc-1f3fc-200d-2640-fe0f","🧜🏽‍♀":"1f9dc-1f3fd-200d-2640-fe0f","🧜🏾‍♀":"1f9dc-1f3fe-200d-2640-fe0f","🧜🏿‍♀":"1f9dc-1f3ff-200d-2640-fe0f","🧜‍♂️":"1f9dc-200d-2642-fe0f","🧜🏻‍♂":"1f9dc-1f3fb-200d-2642-fe0f","🧜🏼‍♂":"1f9dc-1f3fc-200d-2642-fe0f","🧜🏽‍♂":"1f9dc-1f3fd-200d-2642-fe0f","🧜🏾‍♂":"1f9dc-1f3fe-200d-2642-fe0f","🧜🏿‍♂":"1f9dc-1f3ff-200d-2642-fe0f","🧝‍♀️":"1f9dd-200d-2640-fe0f","🧝🏻‍♀":"1f9dd-1f3fb-200d-2640-fe0f","🧝🏼‍♀":"1f9dd-1f3fc-200d-2640-fe0f","🧝🏽‍♀":"1f9dd-1f3fd-200d-2640-fe0f","🧝🏾‍♀":"1f9dd-1f3fe-200d-2640-fe0f","🧝🏿‍♀":"1f9dd-1f3ff-200d-2640-fe0f","🧝‍♂️":"1f9dd-200d-2642-fe0f","🧝🏻‍♂":"1f9dd-1f3fb-200d-2642-fe0f","🧝🏼‍♂":"1f9dd-1f3fc-200d-2642-fe0f","🧝🏽‍♂":"1f9dd-1f3fd-200d-2642-fe0f","🧝🏾‍♂":"1f9dd-1f3fe-200d-2642-fe0f","🧝🏿‍♂":"1f9dd-1f3ff-200d-2642-fe0f","🧞‍♀️":"1f9de-200d-2640-fe0f","🧞‍♂️":"1f9de-200d-2642-fe0f","🧟‍♀️":"1f9df-200d-2640-fe0f","🧟‍♂️":"1f9df-200d-2642-fe0f","🙍‍♂️":"1f64d-200d-2642-fe0f","🙍🏻‍♂":"1f64d-1f3fb-200d-2642-fe0f","🙍🏼‍♂":"1f64d-1f3fc-200d-2642-fe0f","🙍🏽‍♂":"1f64d-1f3fd-200d-2642-fe0f","🙍🏾‍♂":"1f64d-1f3fe-200d-2642-fe0f","🙍🏿‍♂":"1f64d-1f3ff-200d-2642-fe0f","🙍‍♀️":"1f64d-200d-2640-fe0f","🙍🏻‍♀":"1f64d-1f3fb-200d-2640-fe0f","🙍🏼‍♀":"1f64d-1f3fc-200d-2640-fe0f","🙍🏽‍♀":"1f64d-1f3fd-200d-2640-fe0f","🙍🏾‍♀":"1f64d-1f3fe-200d-2640-fe0f","🙍🏿‍♀":"1f64d-1f3ff-200d-2640-fe0f","🙎‍♂️":"1f64e-200d-2642-fe0f","🙎🏻‍♂":"1f64e-1f3fb-200d-2642-fe0f","🙎🏼‍♂":"1f64e-1f3fc-200d-2642-fe0f","🙎🏽‍♂":"1f64e-1f3fd-200d-2642-fe0f","🙎🏾‍♂":"1f64e-1f3fe-200d-2642-fe0f","🙎🏿‍♂":"1f64e-1f3ff-200d-2642-fe0f","🙎‍♀️":"1f64e-200d-2640-fe0f","🙎🏻‍♀":"1f64e-1f3fb-200d-2640-fe0f","🙎🏼‍♀":"1f64e-1f3fc-200d-2640-fe0f","🙎🏽‍♀":"1f64e-1f3fd-200d-2640-fe0f","🙎🏾‍♀":"1f64e-1f3fe-200d-2640-fe0f","🙎🏿‍♀":"1f64e-1f3ff-200d-2640-fe0f","🙅‍♂️":"1f645-200d-2642-fe0f","🙅🏻‍♂":"1f645-1f3fb-200d-2642-fe0f","🙅🏼‍♂":"1f645-1f3fc-200d-2642-fe0f","🙅🏽‍♂":"1f645-1f3fd-200d-2642-fe0f","🙅🏾‍♂":"1f645-1f3fe-200d-2642-fe0f","🙅🏿‍♂":"1f645-1f3ff-200d-2642-fe0f","🙅‍♀️":"1f645-200d-2640-fe0f","🙅🏻‍♀":"1f645-1f3fb-200d-2640-fe0f","🙅🏼‍♀":"1f645-1f3fc-200d-2640-fe0f","🙅🏽‍♀":"1f645-1f3fd-200d-2640-fe0f","🙅🏾‍♀":"1f645-1f3fe-200d-2640-fe0f","🙅🏿‍♀":"1f645-1f3ff-200d-2640-fe0f","🙆‍♂️":"1f646-200d-2642-fe0f","🙆🏻‍♂":"1f646-1f3fb-200d-2642-fe0f","🙆🏼‍♂":"1f646-1f3fc-200d-2642-fe0f","🙆🏽‍♂":"1f646-1f3fd-200d-2642-fe0f","🙆🏾‍♂":"1f646-1f3fe-200d-2642-fe0f","🙆🏿‍♂":"1f646-1f3ff-200d-2642-fe0f","🙆‍♀️":"1f646-200d-2640-fe0f","🙆🏻‍♀":"1f646-1f3fb-200d-2640-fe0f","🙆🏼‍♀":"1f646-1f3fc-200d-2640-fe0f","🙆🏽‍♀":"1f646-1f3fd-200d-2640-fe0f","🙆🏾‍♀":"1f646-1f3fe-200d-2640-fe0f","🙆🏿‍♀":"1f646-1f3ff-200d-2640-fe0f","💁‍♂️":"1f481-200d-2642-fe0f","💁🏻‍♂":"1f481-1f3fb-200d-2642-fe0f","💁🏼‍♂":"1f481-1f3fc-200d-2642-fe0f","💁🏽‍♂":"1f481-1f3fd-200d-2642-fe0f","💁🏾‍♂":"1f481-1f3fe-200d-2642-fe0f","💁🏿‍♂":"1f481-1f3ff-200d-2642-fe0f","💁‍♀️":"1f481-200d-2640-fe0f","💁🏻‍♀":"1f481-1f3fb-200d-2640-fe0f","💁🏼‍♀":"1f481-1f3fc-200d-2640-fe0f","💁🏽‍♀":"1f481-1f3fd-200d-2640-fe0f","💁🏾‍♀":"1f481-1f3fe-200d-2640-fe0f","💁🏿‍♀":"1f481-1f3ff-200d-2640-fe0f","🙋‍♂️":"1f64b-200d-2642-fe0f","🙋🏻‍♂":"1f64b-1f3fb-200d-2642-fe0f","🙋🏼‍♂":"1f64b-1f3fc-200d-2642-fe0f","🙋🏽‍♂":"1f64b-1f3fd-200d-2642-fe0f","🙋🏾‍♂":"1f64b-1f3fe-200d-2642-fe0f","🙋🏿‍♂":"1f64b-1f3ff-200d-2642-fe0f","🙋‍♀️":"1f64b-200d-2640-fe0f","🙋🏻‍♀":"1f64b-1f3fb-200d-2640-fe0f","🙋🏼‍♀":"1f64b-1f3fc-200d-2640-fe0f","🙋🏽‍♀":"1f64b-1f3fd-200d-2640-fe0f","🙋🏾‍♀":"1f64b-1f3fe-200d-2640-fe0f","🙋🏿‍♀":"1f64b-1f3ff-200d-2640-fe0f","🙇‍♂️":"1f647-200d-2642-fe0f","🙇🏻‍♂":"1f647-1f3fb-200d-2642-fe0f","🙇🏼‍♂":"1f647-1f3fc-200d-2642-fe0f","🙇🏽‍♂":"1f647-1f3fd-200d-2642-fe0f","🙇🏾‍♂":"1f647-1f3fe-200d-2642-fe0f","🙇🏿‍♂":"1f647-1f3ff-200d-2642-fe0f","🙇‍♀️":"1f647-200d-2640-fe0f","🙇🏻‍♀":"1f647-1f3fb-200d-2640-fe0f","🙇🏼‍♀":"1f647-1f3fc-200d-2640-fe0f","🙇🏽‍♀":"1f647-1f3fd-200d-2640-fe0f","🙇🏾‍♀":"1f647-1f3fe-200d-2640-fe0f","🙇🏿‍♀":"1f647-1f3ff-200d-2640-fe0f","🤦‍♂️":"1f926-200d-2642-fe0f","🤦🏻‍♂":"1f926-1f3fb-200d-2642-fe0f","🤦🏼‍♂":"1f926-1f3fc-200d-2642-fe0f","🤦🏽‍♂":"1f926-1f3fd-200d-2642-fe0f","🤦🏾‍♂":"1f926-1f3fe-200d-2642-fe0f","🤦🏿‍♂":"1f926-1f3ff-200d-2642-fe0f","🤦‍♀️":"1f926-200d-2640-fe0f","🤦🏻‍♀":"1f926-1f3fb-200d-2640-fe0f","🤦🏼‍♀":"1f926-1f3fc-200d-2640-fe0f","🤦🏽‍♀":"1f926-1f3fd-200d-2640-fe0f","🤦🏾‍♀":"1f926-1f3fe-200d-2640-fe0f","🤦🏿‍♀":"1f926-1f3ff-200d-2640-fe0f","🤷‍♂️":"1f937-200d-2642-fe0f","🤷🏻‍♂":"1f937-1f3fb-200d-2642-fe0f","🤷🏼‍♂":"1f937-1f3fc-200d-2642-fe0f","🤷🏽‍♂":"1f937-1f3fd-200d-2642-fe0f","🤷🏾‍♂":"1f937-1f3fe-200d-2642-fe0f","🤷🏿‍♂":"1f937-1f3ff-200d-2642-fe0f","🤷‍♀️":"1f937-200d-2640-fe0f","🤷🏻‍♀":"1f937-1f3fb-200d-2640-fe0f","🤷🏼‍♀":"1f937-1f3fc-200d-2640-fe0f","🤷🏽‍♀":"1f937-1f3fd-200d-2640-fe0f","🤷🏾‍♀":"1f937-1f3fe-200d-2640-fe0f","🤷🏿‍♀":"1f937-1f3ff-200d-2640-fe0f","💆‍♂️":"1f486-200d-2642-fe0f","💆🏻‍♂":"1f486-1f3fb-200d-2642-fe0f","💆🏼‍♂":"1f486-1f3fc-200d-2642-fe0f","💆🏽‍♂":"1f486-1f3fd-200d-2642-fe0f","💆🏾‍♂":"1f486-1f3fe-200d-2642-fe0f","💆🏿‍♂":"1f486-1f3ff-200d-2642-fe0f","💆‍♀️":"1f486-200d-2640-fe0f","💆🏻‍♀":"1f486-1f3fb-200d-2640-fe0f","💆🏼‍♀":"1f486-1f3fc-200d-2640-fe0f","💆🏽‍♀":"1f486-1f3fd-200d-2640-fe0f","💆🏾‍♀":"1f486-1f3fe-200d-2640-fe0f","💆🏿‍♀":"1f486-1f3ff-200d-2640-fe0f","💇‍♂️":"1f487-200d-2642-fe0f","💇🏻‍♂":"1f487-1f3fb-200d-2642-fe0f","💇🏼‍♂":"1f487-1f3fc-200d-2642-fe0f","💇🏽‍♂":"1f487-1f3fd-200d-2642-fe0f","💇🏾‍♂":"1f487-1f3fe-200d-2642-fe0f","💇🏿‍♂":"1f487-1f3ff-200d-2642-fe0f","💇‍♀️":"1f487-200d-2640-fe0f","💇🏻‍♀":"1f487-1f3fb-200d-2640-fe0f","💇🏼‍♀":"1f487-1f3fc-200d-2640-fe0f","💇🏽‍♀":"1f487-1f3fd-200d-2640-fe0f","💇🏾‍♀":"1f487-1f3fe-200d-2640-fe0f","💇🏿‍♀":"1f487-1f3ff-200d-2640-fe0f","🚶‍♂️":"1f6b6-200d-2642-fe0f","🚶🏻‍♂":"1f6b6-1f3fb-200d-2642-fe0f","🚶🏼‍♂":"1f6b6-1f3fc-200d-2642-fe0f","🚶🏽‍♂":"1f6b6-1f3fd-200d-2642-fe0f","🚶🏾‍♂":"1f6b6-1f3fe-200d-2642-fe0f","🚶🏿‍♂":"1f6b6-1f3ff-200d-2642-fe0f","🚶‍♀️":"1f6b6-200d-2640-fe0f","🚶🏻‍♀":"1f6b6-1f3fb-200d-2640-fe0f","🚶🏼‍♀":"1f6b6-1f3fc-200d-2640-fe0f","🚶🏽‍♀":"1f6b6-1f3fd-200d-2640-fe0f","🚶🏾‍♀":"1f6b6-1f3fe-200d-2640-fe0f","🚶🏿‍♀":"1f6b6-1f3ff-200d-2640-fe0f","🏃‍♂️":"1f3c3-200d-2642-fe0f","🏃🏻‍♂":"1f3c3-1f3fb-200d-2642-fe0f","🏃🏼‍♂":"1f3c3-1f3fc-200d-2642-fe0f","🏃🏽‍♂":"1f3c3-1f3fd-200d-2642-fe0f","🏃🏾‍♂":"1f3c3-1f3fe-200d-2642-fe0f","🏃🏿‍♂":"1f3c3-1f3ff-200d-2642-fe0f","🏃‍♀️":"1f3c3-200d-2640-fe0f","🏃🏻‍♀":"1f3c3-1f3fb-200d-2640-fe0f","🏃🏼‍♀":"1f3c3-1f3fc-200d-2640-fe0f","🏃🏽‍♀":"1f3c3-1f3fd-200d-2640-fe0f","🏃🏾‍♀":"1f3c3-1f3fe-200d-2640-fe0f","🏃🏿‍♀":"1f3c3-1f3ff-200d-2640-fe0f","👯‍♂️":"1f46f-200d-2642-fe0f","👯‍♀️":"1f46f-200d-2640-fe0f","🧖‍♀️":"1f9d6-200d-2640-fe0f","🧖🏻‍♀":"1f9d6-1f3fb-200d-2640-fe0f","🧖🏼‍♀":"1f9d6-1f3fc-200d-2640-fe0f","🧖🏽‍♀":"1f9d6-1f3fd-200d-2640-fe0f","🧖🏾‍♀":"1f9d6-1f3fe-200d-2640-fe0f","🧖🏿‍♀":"1f9d6-1f3ff-200d-2640-fe0f","🧖‍♂️":"1f9d6-200d-2642-fe0f","🧖🏻‍♂":"1f9d6-1f3fb-200d-2642-fe0f","🧖🏼‍♂":"1f9d6-1f3fc-200d-2642-fe0f","🧖🏽‍♂":"1f9d6-1f3fd-200d-2642-fe0f","🧖🏾‍♂":"1f9d6-1f3fe-200d-2642-fe0f","🧖🏿‍♂":"1f9d6-1f3ff-200d-2642-fe0f","🧗‍♀️":"1f9d7-200d-2640-fe0f","🧗🏻‍♀":"1f9d7-1f3fb-200d-2640-fe0f","🧗🏼‍♀":"1f9d7-1f3fc-200d-2640-fe0f","🧗🏽‍♀":"1f9d7-1f3fd-200d-2640-fe0f","🧗🏾‍♀":"1f9d7-1f3fe-200d-2640-fe0f","🧗🏿‍♀":"1f9d7-1f3ff-200d-2640-fe0f","🧗‍♂️":"1f9d7-200d-2642-fe0f","🧗🏻‍♂":"1f9d7-1f3fb-200d-2642-fe0f","🧗🏼‍♂":"1f9d7-1f3fc-200d-2642-fe0f","🧗🏽‍♂":"1f9d7-1f3fd-200d-2642-fe0f","🧗🏾‍♂":"1f9d7-1f3fe-200d-2642-fe0f","🧗🏿‍♂":"1f9d7-1f3ff-200d-2642-fe0f","🧘‍♀️":"1f9d8-200d-2640-fe0f","🧘🏻‍♀":"1f9d8-1f3fb-200d-2640-fe0f","🧘🏼‍♀":"1f9d8-1f3fc-200d-2640-fe0f","🧘🏽‍♀":"1f9d8-1f3fd-200d-2640-fe0f","🧘🏾‍♀":"1f9d8-1f3fe-200d-2640-fe0f","🧘🏿‍♀":"1f9d8-1f3ff-200d-2640-fe0f","🧘‍♂️":"1f9d8-200d-2642-fe0f","🧘🏻‍♂":"1f9d8-1f3fb-200d-2642-fe0f","🧘🏼‍♂":"1f9d8-1f3fc-200d-2642-fe0f","🧘🏽‍♂":"1f9d8-1f3fd-200d-2642-fe0f","🧘🏾‍♂":"1f9d8-1f3fe-200d-2642-fe0f","🧘🏿‍♂":"1f9d8-1f3ff-200d-2642-fe0f","🏌‍♂️":"1f3cc-fe0f-200d-2642-fe0f","🏌️‍♂":"1f3cc-fe0f-200d-2642-fe0f","🏌🏻‍♂":"1f3cc-1f3fb-200d-2642-fe0f","🏌🏼‍♂":"1f3cc-1f3fc-200d-2642-fe0f","🏌🏽‍♂":"1f3cc-1f3fd-200d-2642-fe0f","🏌🏾‍♂":"1f3cc-1f3fe-200d-2642-fe0f","🏌🏿‍♂":"1f3cc-1f3ff-200d-2642-fe0f","🏌‍♀️":"1f3cc-fe0f-200d-2640-fe0f","🏌️‍♀":"1f3cc-fe0f-200d-2640-fe0f","🏌🏻‍♀":"1f3cc-1f3fb-200d-2640-fe0f","🏌🏼‍♀":"1f3cc-1f3fc-200d-2640-fe0f","🏌🏽‍♀":"1f3cc-1f3fd-200d-2640-fe0f","🏌🏾‍♀":"1f3cc-1f3fe-200d-2640-fe0f","🏌🏿‍♀":"1f3cc-1f3ff-200d-2640-fe0f","🏄‍♂️":"1f3c4-200d-2642-fe0f","🏄🏻‍♂":"1f3c4-1f3fb-200d-2642-fe0f","🏄🏼‍♂":"1f3c4-1f3fc-200d-2642-fe0f","🏄🏽‍♂":"1f3c4-1f3fd-200d-2642-fe0f","🏄🏾‍♂":"1f3c4-1f3fe-200d-2642-fe0f","🏄🏿‍♂":"1f3c4-1f3ff-200d-2642-fe0f","🏄‍♀️":"1f3c4-200d-2640-fe0f","🏄🏻‍♀":"1f3c4-1f3fb-200d-2640-fe0f","🏄🏼‍♀":"1f3c4-1f3fc-200d-2640-fe0f","🏄🏽‍♀":"1f3c4-1f3fd-200d-2640-fe0f","🏄🏾‍♀":"1f3c4-1f3fe-200d-2640-fe0f","🏄🏿‍♀":"1f3c4-1f3ff-200d-2640-fe0f","🚣‍♂️":"1f6a3-200d-2642-fe0f","🚣🏻‍♂":"1f6a3-1f3fb-200d-2642-fe0f","🚣🏼‍♂":"1f6a3-1f3fc-200d-2642-fe0f","🚣🏽‍♂":"1f6a3-1f3fd-200d-2642-fe0f","🚣🏾‍♂":"1f6a3-1f3fe-200d-2642-fe0f","🚣🏿‍♂":"1f6a3-1f3ff-200d-2642-fe0f","🚣‍♀️":"1f6a3-200d-2640-fe0f","🚣🏻‍♀":"1f6a3-1f3fb-200d-2640-fe0f","🚣🏼‍♀":"1f6a3-1f3fc-200d-2640-fe0f","🚣🏽‍♀":"1f6a3-1f3fd-200d-2640-fe0f","🚣🏾‍♀":"1f6a3-1f3fe-200d-2640-fe0f","🚣🏿‍♀":"1f6a3-1f3ff-200d-2640-fe0f","🏊‍♂️":"1f3ca-200d-2642-fe0f","🏊🏻‍♂":"1f3ca-1f3fb-200d-2642-fe0f","🏊🏼‍♂":"1f3ca-1f3fc-200d-2642-fe0f","🏊🏽‍♂":"1f3ca-1f3fd-200d-2642-fe0f","🏊🏾‍♂":"1f3ca-1f3fe-200d-2642-fe0f","🏊🏿‍♂":"1f3ca-1f3ff-200d-2642-fe0f","🏊‍♀️":"1f3ca-200d-2640-fe0f","🏊🏻‍♀":"1f3ca-1f3fb-200d-2640-fe0f","🏊🏼‍♀":"1f3ca-1f3fc-200d-2640-fe0f","🏊🏽‍♀":"1f3ca-1f3fd-200d-2640-fe0f","🏊🏾‍♀":"1f3ca-1f3fe-200d-2640-fe0f","🏊🏿‍♀":"1f3ca-1f3ff-200d-2640-fe0f","⛹‍♂️":"26f9-fe0f-200d-2642-fe0f","⛹️‍♂":"26f9-fe0f-200d-2642-fe0f","⛹🏻‍♂":"26f9-1f3fb-200d-2642-fe0f","⛹🏼‍♂":"26f9-1f3fc-200d-2642-fe0f","⛹🏽‍♂":"26f9-1f3fd-200d-2642-fe0f","⛹🏾‍♂":"26f9-1f3fe-200d-2642-fe0f","⛹🏿‍♂":"26f9-1f3ff-200d-2642-fe0f","⛹‍♀️":"26f9-fe0f-200d-2640-fe0f","⛹️‍♀":"26f9-fe0f-200d-2640-fe0f","⛹🏻‍♀":"26f9-1f3fb-200d-2640-fe0f","⛹🏼‍♀":"26f9-1f3fc-200d-2640-fe0f","⛹🏽‍♀":"26f9-1f3fd-200d-2640-fe0f","⛹🏾‍♀":"26f9-1f3fe-200d-2640-fe0f","⛹🏿‍♀":"26f9-1f3ff-200d-2640-fe0f","🏋‍♂️":"1f3cb-fe0f-200d-2642-fe0f","🏋️‍♂":"1f3cb-fe0f-200d-2642-fe0f","🏋🏻‍♂":"1f3cb-1f3fb-200d-2642-fe0f","🏋🏼‍♂":"1f3cb-1f3fc-200d-2642-fe0f","🏋🏽‍♂":"1f3cb-1f3fd-200d-2642-fe0f","🏋🏾‍♂":"1f3cb-1f3fe-200d-2642-fe0f","🏋🏿‍♂":"1f3cb-1f3ff-200d-2642-fe0f","🏋‍♀️":"1f3cb-fe0f-200d-2640-fe0f","🏋️‍♀":"1f3cb-fe0f-200d-2640-fe0f","🏋🏻‍♀":"1f3cb-1f3fb-200d-2640-fe0f","🏋🏼‍♀":"1f3cb-1f3fc-200d-2640-fe0f","🏋🏽‍♀":"1f3cb-1f3fd-200d-2640-fe0f","🏋🏾‍♀":"1f3cb-1f3fe-200d-2640-fe0f","🏋🏿‍♀":"1f3cb-1f3ff-200d-2640-fe0f","🚴‍♂️":"1f6b4-200d-2642-fe0f","🚴🏻‍♂":"1f6b4-1f3fb-200d-2642-fe0f","🚴🏼‍♂":"1f6b4-1f3fc-200d-2642-fe0f","🚴🏽‍♂":"1f6b4-1f3fd-200d-2642-fe0f","🚴🏾‍♂":"1f6b4-1f3fe-200d-2642-fe0f","🚴🏿‍♂":"1f6b4-1f3ff-200d-2642-fe0f","🚴‍♀️":"1f6b4-200d-2640-fe0f","🚴🏻‍♀":"1f6b4-1f3fb-200d-2640-fe0f","🚴🏼‍♀":"1f6b4-1f3fc-200d-2640-fe0f","🚴🏽‍♀":"1f6b4-1f3fd-200d-2640-fe0f","🚴🏾‍♀":"1f6b4-1f3fe-200d-2640-fe0f","🚴🏿‍♀":"1f6b4-1f3ff-200d-2640-fe0f","🚵‍♂️":"1f6b5-200d-2642-fe0f","🚵🏻‍♂":"1f6b5-1f3fb-200d-2642-fe0f","🚵🏼‍♂":"1f6b5-1f3fc-200d-2642-fe0f","🚵🏽‍♂":"1f6b5-1f3fd-200d-2642-fe0f","🚵🏾‍♂":"1f6b5-1f3fe-200d-2642-fe0f","🚵🏿‍♂":"1f6b5-1f3ff-200d-2642-fe0f","🚵‍♀️":"1f6b5-200d-2640-fe0f","🚵🏻‍♀":"1f6b5-1f3fb-200d-2640-fe0f","🚵🏼‍♀":"1f6b5-1f3fc-200d-2640-fe0f","🚵🏽‍♀":"1f6b5-1f3fd-200d-2640-fe0f","🚵🏾‍♀":"1f6b5-1f3fe-200d-2640-fe0f","🚵🏿‍♀":"1f6b5-1f3ff-200d-2640-fe0f","🤸‍♂️":"1f938-200d-2642-fe0f","🤸🏻‍♂":"1f938-1f3fb-200d-2642-fe0f","🤸🏼‍♂":"1f938-1f3fc-200d-2642-fe0f","🤸🏽‍♂":"1f938-1f3fd-200d-2642-fe0f","🤸🏾‍♂":"1f938-1f3fe-200d-2642-fe0f","🤸🏿‍♂":"1f938-1f3ff-200d-2642-fe0f","🤸‍♀️":"1f938-200d-2640-fe0f","🤸🏻‍♀":"1f938-1f3fb-200d-2640-fe0f","🤸🏼‍♀":"1f938-1f3fc-200d-2640-fe0f","🤸🏽‍♀":"1f938-1f3fd-200d-2640-fe0f","🤸🏾‍♀":"1f938-1f3fe-200d-2640-fe0f","🤸🏿‍♀":"1f938-1f3ff-200d-2640-fe0f","🤼‍♂️":"1f93c-200d-2642-fe0f","🤼‍♀️":"1f93c-200d-2640-fe0f","🤽‍♂️":"1f93d-200d-2642-fe0f","🤽🏻‍♂":"1f93d-1f3fb-200d-2642-fe0f","🤽🏼‍♂":"1f93d-1f3fc-200d-2642-fe0f","🤽🏽‍♂":"1f93d-1f3fd-200d-2642-fe0f","🤽🏾‍♂":"1f93d-1f3fe-200d-2642-fe0f","🤽🏿‍♂":"1f93d-1f3ff-200d-2642-fe0f","🤽‍♀️":"1f93d-200d-2640-fe0f","🤽🏻‍♀":"1f93d-1f3fb-200d-2640-fe0f","🤽🏼‍♀":"1f93d-1f3fc-200d-2640-fe0f","🤽🏽‍♀":"1f93d-1f3fd-200d-2640-fe0f","🤽🏾‍♀":"1f93d-1f3fe-200d-2640-fe0f","🤽🏿‍♀":"1f93d-1f3ff-200d-2640-fe0f","🤾‍♂️":"1f93e-200d-2642-fe0f","🤾🏻‍♂":"1f93e-1f3fb-200d-2642-fe0f","🤾🏼‍♂":"1f93e-1f3fc-200d-2642-fe0f","🤾🏽‍♂":"1f93e-1f3fd-200d-2642-fe0f","🤾🏾‍♂":"1f93e-1f3fe-200d-2642-fe0f","🤾🏿‍♂":"1f93e-1f3ff-200d-2642-fe0f","🤾‍♀️":"1f93e-200d-2640-fe0f","🤾🏻‍♀":"1f93e-1f3fb-200d-2640-fe0f","🤾🏼‍♀":"1f93e-1f3fc-200d-2640-fe0f","🤾🏽‍♀":"1f93e-1f3fd-200d-2640-fe0f","🤾🏾‍♀":"1f93e-1f3fe-200d-2640-fe0f","🤾🏿‍♀":"1f93e-1f3ff-200d-2640-fe0f","🤹‍♂️":"1f939-200d-2642-fe0f","🤹🏻‍♂":"1f939-1f3fb-200d-2642-fe0f","🤹🏼‍♂":"1f939-1f3fc-200d-2642-fe0f","🤹🏽‍♂":"1f939-1f3fd-200d-2642-fe0f","🤹🏾‍♂":"1f939-1f3fe-200d-2642-fe0f","🤹🏿‍♂":"1f939-1f3ff-200d-2642-fe0f","🤹‍♀️":"1f939-200d-2640-fe0f","🤹🏻‍♀":"1f939-1f3fb-200d-2640-fe0f","🤹🏼‍♀":"1f939-1f3fc-200d-2640-fe0f","🤹🏽‍♀":"1f939-1f3fd-200d-2640-fe0f","🤹🏾‍♀":"1f939-1f3fe-200d-2640-fe0f","🤹🏿‍♀":"1f939-1f3ff-200d-2640-fe0f","👁‍🗨️":"1f441-200d-1f5e8","👁️‍🗨":"1f441-200d-1f5e8","🏳️‍🌈":"1f3f3-fe0f-200d-1f308","👨🏻‍⚕️":"1f468-1f3fb-200d-2695-fe0f","👨🏼‍⚕️":"1f468-1f3fc-200d-2695-fe0f","👨🏽‍⚕️":"1f468-1f3fd-200d-2695-fe0f","👨🏾‍⚕️":"1f468-1f3fe-200d-2695-fe0f","👨🏿‍⚕️":"1f468-1f3ff-200d-2695-fe0f","👩🏻‍⚕️":"1f469-1f3fb-200d-2695-fe0f","👩🏼‍⚕️":"1f469-1f3fc-200d-2695-fe0f","👩🏽‍⚕️":"1f469-1f3fd-200d-2695-fe0f","👩🏾‍⚕️":"1f469-1f3fe-200d-2695-fe0f","👩🏿‍⚕️":"1f469-1f3ff-200d-2695-fe0f","👨🏻‍⚖️":"1f468-1f3fb-200d-2696-fe0f","👨🏼‍⚖️":"1f468-1f3fc-200d-2696-fe0f","👨🏽‍⚖️":"1f468-1f3fd-200d-2696-fe0f","👨🏾‍⚖️":"1f468-1f3fe-200d-2696-fe0f","👨🏿‍⚖️":"1f468-1f3ff-200d-2696-fe0f","👩🏻‍⚖️":"1f469-1f3fb-200d-2696-fe0f","👩🏼‍⚖️":"1f469-1f3fc-200d-2696-fe0f","👩🏽‍⚖️":"1f469-1f3fd-200d-2696-fe0f","👩🏾‍⚖️":"1f469-1f3fe-200d-2696-fe0f","👩🏿‍⚖️":"1f469-1f3ff-200d-2696-fe0f","👨🏻‍✈️":"1f468-1f3fb-200d-2708-fe0f","👨🏼‍✈️":"1f468-1f3fc-200d-2708-fe0f","👨🏽‍✈️":"1f468-1f3fd-200d-2708-fe0f","👨🏾‍✈️":"1f468-1f3fe-200d-2708-fe0f","👨🏿‍✈️":"1f468-1f3ff-200d-2708-fe0f","👩🏻‍✈️":"1f469-1f3fb-200d-2708-fe0f","👩🏼‍✈️":"1f469-1f3fc-200d-2708-fe0f","👩🏽‍✈️":"1f469-1f3fd-200d-2708-fe0f","👩🏾‍✈️":"1f469-1f3fe-200d-2708-fe0f","👩🏿‍✈️":"1f469-1f3ff-200d-2708-fe0f","👮🏻‍♂️":"1f46e-1f3fb-200d-2642-fe0f","👮🏼‍♂️":"1f46e-1f3fc-200d-2642-fe0f","👮🏽‍♂️":"1f46e-1f3fd-200d-2642-fe0f","👮🏾‍♂️":"1f46e-1f3fe-200d-2642-fe0f","👮🏿‍♂️":"1f46e-1f3ff-200d-2642-fe0f","👮🏻‍♀️":"1f46e-1f3fb-200d-2640-fe0f","👮🏼‍♀️":"1f46e-1f3fc-200d-2640-fe0f","👮🏽‍♀️":"1f46e-1f3fd-200d-2640-fe0f","👮🏾‍♀️":"1f46e-1f3fe-200d-2640-fe0f","👮🏿‍♀️":"1f46e-1f3ff-200d-2640-fe0f","🕵️‍♂️":"1f575-fe0f-200d-2642-fe0f","🕵🏻‍♂️":"1f575-1f3fb-200d-2642-fe0f","🕵🏼‍♂️":"1f575-1f3fc-200d-2642-fe0f","🕵🏽‍♂️":"1f575-1f3fd-200d-2642-fe0f","🕵🏾‍♂️":"1f575-1f3fe-200d-2642-fe0f","🕵🏿‍♂️":"1f575-1f3ff-200d-2642-fe0f","🕵️‍♀️":"1f575-fe0f-200d-2640-fe0f","🕵🏻‍♀️":"1f575-1f3fb-200d-2640-fe0f","🕵🏼‍♀️":"1f575-1f3fc-200d-2640-fe0f","🕵🏽‍♀️":"1f575-1f3fd-200d-2640-fe0f","🕵🏾‍♀️":"1f575-1f3fe-200d-2640-fe0f","🕵🏿‍♀️":"1f575-1f3ff-200d-2640-fe0f","💂🏻‍♂️":"1f482-1f3fb-200d-2642-fe0f","💂🏼‍♂️":"1f482-1f3fc-200d-2642-fe0f","💂🏽‍♂️":"1f482-1f3fd-200d-2642-fe0f","💂🏾‍♂️":"1f482-1f3fe-200d-2642-fe0f","💂🏿‍♂️":"1f482-1f3ff-200d-2642-fe0f","💂🏻‍♀️":"1f482-1f3fb-200d-2640-fe0f","💂🏼‍♀️":"1f482-1f3fc-200d-2640-fe0f","💂🏽‍♀️":"1f482-1f3fd-200d-2640-fe0f","💂🏾‍♀️":"1f482-1f3fe-200d-2640-fe0f","💂🏿‍♀️":"1f482-1f3ff-200d-2640-fe0f","👷🏻‍♂️":"1f477-1f3fb-200d-2642-fe0f","👷🏼‍♂️":"1f477-1f3fc-200d-2642-fe0f","👷🏽‍♂️":"1f477-1f3fd-200d-2642-fe0f","👷🏾‍♂️":"1f477-1f3fe-200d-2642-fe0f","👷🏿‍♂️":"1f477-1f3ff-200d-2642-fe0f","👷🏻‍♀️":"1f477-1f3fb-200d-2640-fe0f","👷🏼‍♀️":"1f477-1f3fc-200d-2640-fe0f","👷🏽‍♀️":"1f477-1f3fd-200d-2640-fe0f","👷🏾‍♀️":"1f477-1f3fe-200d-2640-fe0f","👷🏿‍♀️":"1f477-1f3ff-200d-2640-fe0f","👳🏻‍♂️":"1f473-1f3fb-200d-2642-fe0f","👳🏼‍♂️":"1f473-1f3fc-200d-2642-fe0f","👳🏽‍♂️":"1f473-1f3fd-200d-2642-fe0f","👳🏾‍♂️":"1f473-1f3fe-200d-2642-fe0f","👳🏿‍♂️":"1f473-1f3ff-200d-2642-fe0f","👳🏻‍♀️":"1f473-1f3fb-200d-2640-fe0f","👳🏼‍♀️":"1f473-1f3fc-200d-2640-fe0f","👳🏽‍♀️":"1f473-1f3fd-200d-2640-fe0f","👳🏾‍♀️":"1f473-1f3fe-200d-2640-fe0f","👳🏿‍♀️":"1f473-1f3ff-200d-2640-fe0f","👱🏻‍♂️":"1f471-1f3fb-200d-2642-fe0f","👱🏼‍♂️":"1f471-1f3fc-200d-2642-fe0f","👱🏽‍♂️":"1f471-1f3fd-200d-2642-fe0f","👱🏾‍♂️":"1f471-1f3fe-200d-2642-fe0f","👱🏿‍♂️":"1f471-1f3ff-200d-2642-fe0f","👱🏻‍♀️":"1f471-1f3fb-200d-2640-fe0f","👱🏼‍♀️":"1f471-1f3fc-200d-2640-fe0f","👱🏽‍♀️":"1f471-1f3fd-200d-2640-fe0f","👱🏾‍♀️":"1f471-1f3fe-200d-2640-fe0f","👱🏿‍♀️":"1f471-1f3ff-200d-2640-fe0f","🧙🏻‍♀️":"1f9d9-1f3fb-200d-2640-fe0f","🧙🏼‍♀️":"1f9d9-1f3fc-200d-2640-fe0f","🧙🏽‍♀️":"1f9d9-1f3fd-200d-2640-fe0f","🧙🏾‍♀️":"1f9d9-1f3fe-200d-2640-fe0f","🧙🏿‍♀️":"1f9d9-1f3ff-200d-2640-fe0f","🧙🏻‍♂️":"1f9d9-1f3fb-200d-2642-fe0f","🧙🏼‍♂️":"1f9d9-1f3fc-200d-2642-fe0f","🧙🏽‍♂️":"1f9d9-1f3fd-200d-2642-fe0f","🧙🏾‍♂️":"1f9d9-1f3fe-200d-2642-fe0f","🧙🏿‍♂️":"1f9d9-1f3ff-200d-2642-fe0f","🧚🏻‍♀️":"1f9da-1f3fb-200d-2640-fe0f","🧚🏼‍♀️":"1f9da-1f3fc-200d-2640-fe0f","🧚🏽‍♀️":"1f9da-1f3fd-200d-2640-fe0f","🧚🏾‍♀️":"1f9da-1f3fe-200d-2640-fe0f","🧚🏿‍♀️":"1f9da-1f3ff-200d-2640-fe0f","🧚🏻‍♂️":"1f9da-1f3fb-200d-2642-fe0f","🧚🏼‍♂️":"1f9da-1f3fc-200d-2642-fe0f","🧚🏽‍♂️":"1f9da-1f3fd-200d-2642-fe0f","🧚🏾‍♂️":"1f9da-1f3fe-200d-2642-fe0f","🧚🏿‍♂️":"1f9da-1f3ff-200d-2642-fe0f","🧛🏻‍♀️":"1f9db-1f3fb-200d-2640-fe0f","🧛🏼‍♀️":"1f9db-1f3fc-200d-2640-fe0f","🧛🏽‍♀️":"1f9db-1f3fd-200d-2640-fe0f","🧛🏾‍♀️":"1f9db-1f3fe-200d-2640-fe0f","🧛🏿‍♀️":"1f9db-1f3ff-200d-2640-fe0f","🧛🏻‍♂️":"1f9db-1f3fb-200d-2642-fe0f","🧛🏼‍♂️":"1f9db-1f3fc-200d-2642-fe0f","🧛🏽‍♂️":"1f9db-1f3fd-200d-2642-fe0f","🧛🏾‍♂️":"1f9db-1f3fe-200d-2642-fe0f","🧛🏿‍♂️":"1f9db-1f3ff-200d-2642-fe0f","🧜🏻‍♀️":"1f9dc-1f3fb-200d-2640-fe0f","🧜🏼‍♀️":"1f9dc-1f3fc-200d-2640-fe0f","🧜🏽‍♀️":"1f9dc-1f3fd-200d-2640-fe0f","🧜🏾‍♀️":"1f9dc-1f3fe-200d-2640-fe0f","🧜🏿‍♀️":"1f9dc-1f3ff-200d-2640-fe0f","🧜🏻‍♂️":"1f9dc-1f3fb-200d-2642-fe0f","🧜🏼‍♂️":"1f9dc-1f3fc-200d-2642-fe0f","🧜🏽‍♂️":"1f9dc-1f3fd-200d-2642-fe0f","🧜🏾‍♂️":"1f9dc-1f3fe-200d-2642-fe0f","🧜🏿‍♂️":"1f9dc-1f3ff-200d-2642-fe0f","🧝🏻‍♀️":"1f9dd-1f3fb-200d-2640-fe0f","🧝🏼‍♀️":"1f9dd-1f3fc-200d-2640-fe0f","🧝🏽‍♀️":"1f9dd-1f3fd-200d-2640-fe0f","🧝🏾‍♀️":"1f9dd-1f3fe-200d-2640-fe0f","🧝🏿‍♀️":"1f9dd-1f3ff-200d-2640-fe0f","🧝🏻‍♂️":"1f9dd-1f3fb-200d-2642-fe0f","🧝🏼‍♂️":"1f9dd-1f3fc-200d-2642-fe0f","🧝🏽‍♂️":"1f9dd-1f3fd-200d-2642-fe0f","🧝🏾‍♂️":"1f9dd-1f3fe-200d-2642-fe0f","🧝🏿‍♂️":"1f9dd-1f3ff-200d-2642-fe0f","🙍🏻‍♂️":"1f64d-1f3fb-200d-2642-fe0f","🙍🏼‍♂️":"1f64d-1f3fc-200d-2642-fe0f","🙍🏽‍♂️":"1f64d-1f3fd-200d-2642-fe0f","🙍🏾‍♂️":"1f64d-1f3fe-200d-2642-fe0f","🙍🏿‍♂️":"1f64d-1f3ff-200d-2642-fe0f","🙍🏻‍♀️":"1f64d-1f3fb-200d-2640-fe0f","🙍🏼‍♀️":"1f64d-1f3fc-200d-2640-fe0f","🙍🏽‍♀️":"1f64d-1f3fd-200d-2640-fe0f","🙍🏾‍♀️":"1f64d-1f3fe-200d-2640-fe0f","🙍🏿‍♀️":"1f64d-1f3ff-200d-2640-fe0f","🙎🏻‍♂️":"1f64e-1f3fb-200d-2642-fe0f","🙎🏼‍♂️":"1f64e-1f3fc-200d-2642-fe0f","🙎🏽‍♂️":"1f64e-1f3fd-200d-2642-fe0f","🙎🏾‍♂️":"1f64e-1f3fe-200d-2642-fe0f","🙎🏿‍♂️":"1f64e-1f3ff-200d-2642-fe0f","🙎🏻‍♀️":"1f64e-1f3fb-200d-2640-fe0f","🙎🏼‍♀️":"1f64e-1f3fc-200d-2640-fe0f","🙎🏽‍♀️":"1f64e-1f3fd-200d-2640-fe0f","🙎🏾‍♀️":"1f64e-1f3fe-200d-2640-fe0f","🙎🏿‍♀️":"1f64e-1f3ff-200d-2640-fe0f","🙅🏻‍♂️":"1f645-1f3fb-200d-2642-fe0f","🙅🏼‍♂️":"1f645-1f3fc-200d-2642-fe0f","🙅🏽‍♂️":"1f645-1f3fd-200d-2642-fe0f","🙅🏾‍♂️":"1f645-1f3fe-200d-2642-fe0f","🙅🏿‍♂️":"1f645-1f3ff-200d-2642-fe0f","🙅🏻‍♀️":"1f645-1f3fb-200d-2640-fe0f","🙅🏼‍♀️":"1f645-1f3fc-200d-2640-fe0f","🙅🏽‍♀️":"1f645-1f3fd-200d-2640-fe0f","🙅🏾‍♀️":"1f645-1f3fe-200d-2640-fe0f","🙅🏿‍♀️":"1f645-1f3ff-200d-2640-fe0f","🙆🏻‍♂️":"1f646-1f3fb-200d-2642-fe0f","🙆🏼‍♂️":"1f646-1f3fc-200d-2642-fe0f","🙆🏽‍♂️":"1f646-1f3fd-200d-2642-fe0f","🙆🏾‍♂️":"1f646-1f3fe-200d-2642-fe0f","🙆🏿‍♂️":"1f646-1f3ff-200d-2642-fe0f","🙆🏻‍♀️":"1f646-1f3fb-200d-2640-fe0f","🙆🏼‍♀️":"1f646-1f3fc-200d-2640-fe0f","🙆🏽‍♀️":"1f646-1f3fd-200d-2640-fe0f","🙆🏾‍♀️":"1f646-1f3fe-200d-2640-fe0f","🙆🏿‍♀️":"1f646-1f3ff-200d-2640-fe0f","💁🏻‍♂️":"1f481-1f3fb-200d-2642-fe0f","💁🏼‍♂️":"1f481-1f3fc-200d-2642-fe0f","💁🏽‍♂️":"1f481-1f3fd-200d-2642-fe0f","💁🏾‍♂️":"1f481-1f3fe-200d-2642-fe0f","💁🏿‍♂️":"1f481-1f3ff-200d-2642-fe0f","💁🏻‍♀️":"1f481-1f3fb-200d-2640-fe0f","💁🏼‍♀️":"1f481-1f3fc-200d-2640-fe0f","💁🏽‍♀️":"1f481-1f3fd-200d-2640-fe0f","💁🏾‍♀️":"1f481-1f3fe-200d-2640-fe0f","💁🏿‍♀️":"1f481-1f3ff-200d-2640-fe0f","🙋🏻‍♂️":"1f64b-1f3fb-200d-2642-fe0f","🙋🏼‍♂️":"1f64b-1f3fc-200d-2642-fe0f","🙋🏽‍♂️":"1f64b-1f3fd-200d-2642-fe0f","🙋🏾‍♂️":"1f64b-1f3fe-200d-2642-fe0f","🙋🏿‍♂️":"1f64b-1f3ff-200d-2642-fe0f","🙋🏻‍♀️":"1f64b-1f3fb-200d-2640-fe0f","🙋🏼‍♀️":"1f64b-1f3fc-200d-2640-fe0f","🙋🏽‍♀️":"1f64b-1f3fd-200d-2640-fe0f","🙋🏾‍♀️":"1f64b-1f3fe-200d-2640-fe0f","🙋🏿‍♀️":"1f64b-1f3ff-200d-2640-fe0f","🙇🏻‍♂️":"1f647-1f3fb-200d-2642-fe0f","🙇🏼‍♂️":"1f647-1f3fc-200d-2642-fe0f","🙇🏽‍♂️":"1f647-1f3fd-200d-2642-fe0f","🙇🏾‍♂️":"1f647-1f3fe-200d-2642-fe0f","🙇🏿‍♂️":"1f647-1f3ff-200d-2642-fe0f","🙇🏻‍♀️":"1f647-1f3fb-200d-2640-fe0f","🙇🏼‍♀️":"1f647-1f3fc-200d-2640-fe0f","🙇🏽‍♀️":"1f647-1f3fd-200d-2640-fe0f","🙇🏾‍♀️":"1f647-1f3fe-200d-2640-fe0f","🙇🏿‍♀️":"1f647-1f3ff-200d-2640-fe0f","🤦🏻‍♂️":"1f926-1f3fb-200d-2642-fe0f","🤦🏼‍♂️":"1f926-1f3fc-200d-2642-fe0f","🤦🏽‍♂️":"1f926-1f3fd-200d-2642-fe0f","🤦🏾‍♂️":"1f926-1f3fe-200d-2642-fe0f","🤦🏿‍♂️":"1f926-1f3ff-200d-2642-fe0f","🤦🏻‍♀️":"1f926-1f3fb-200d-2640-fe0f","🤦🏼‍♀️":"1f926-1f3fc-200d-2640-fe0f","🤦🏽‍♀️":"1f926-1f3fd-200d-2640-fe0f","🤦🏾‍♀️":"1f926-1f3fe-200d-2640-fe0f","🤦🏿‍♀️":"1f926-1f3ff-200d-2640-fe0f","🤷🏻‍♂️":"1f937-1f3fb-200d-2642-fe0f","🤷🏼‍♂️":"1f937-1f3fc-200d-2642-fe0f","🤷🏽‍♂️":"1f937-1f3fd-200d-2642-fe0f","🤷🏾‍♂️":"1f937-1f3fe-200d-2642-fe0f","🤷🏿‍♂️":"1f937-1f3ff-200d-2642-fe0f","🤷🏻‍♀️":"1f937-1f3fb-200d-2640-fe0f","🤷🏼‍♀️":"1f937-1f3fc-200d-2640-fe0f","🤷🏽‍♀️":"1f937-1f3fd-200d-2640-fe0f","🤷🏾‍♀️":"1f937-1f3fe-200d-2640-fe0f","🤷🏿‍♀️":"1f937-1f3ff-200d-2640-fe0f","💆🏻‍♂️":"1f486-1f3fb-200d-2642-fe0f","💆🏼‍♂️":"1f486-1f3fc-200d-2642-fe0f","💆🏽‍♂️":"1f486-1f3fd-200d-2642-fe0f","💆🏾‍♂️":"1f486-1f3fe-200d-2642-fe0f","💆🏿‍♂️":"1f486-1f3ff-200d-2642-fe0f","💆🏻‍♀️":"1f486-1f3fb-200d-2640-fe0f","💆🏼‍♀️":"1f486-1f3fc-200d-2640-fe0f","💆🏽‍♀️":"1f486-1f3fd-200d-2640-fe0f","💆🏾‍♀️":"1f486-1f3fe-200d-2640-fe0f","💆🏿‍♀️":"1f486-1f3ff-200d-2640-fe0f","💇🏻‍♂️":"1f487-1f3fb-200d-2642-fe0f","💇🏼‍♂️":"1f487-1f3fc-200d-2642-fe0f","💇🏽‍♂️":"1f487-1f3fd-200d-2642-fe0f","💇🏾‍♂️":"1f487-1f3fe-200d-2642-fe0f","💇🏿‍♂️":"1f487-1f3ff-200d-2642-fe0f","💇🏻‍♀️":"1f487-1f3fb-200d-2640-fe0f","💇🏼‍♀️":"1f487-1f3fc-200d-2640-fe0f","💇🏽‍♀️":"1f487-1f3fd-200d-2640-fe0f","💇🏾‍♀️":"1f487-1f3fe-200d-2640-fe0f","💇🏿‍♀️":"1f487-1f3ff-200d-2640-fe0f","🚶🏻‍♂️":"1f6b6-1f3fb-200d-2642-fe0f","🚶🏼‍♂️":"1f6b6-1f3fc-200d-2642-fe0f","🚶🏽‍♂️":"1f6b6-1f3fd-200d-2642-fe0f","🚶🏾‍♂️":"1f6b6-1f3fe-200d-2642-fe0f","🚶🏿‍♂️":"1f6b6-1f3ff-200d-2642-fe0f","🚶🏻‍♀️":"1f6b6-1f3fb-200d-2640-fe0f","🚶🏼‍♀️":"1f6b6-1f3fc-200d-2640-fe0f","🚶🏽‍♀️":"1f6b6-1f3fd-200d-2640-fe0f","🚶🏾‍♀️":"1f6b6-1f3fe-200d-2640-fe0f","🚶🏿‍♀️":"1f6b6-1f3ff-200d-2640-fe0f","🏃🏻‍♂️":"1f3c3-1f3fb-200d-2642-fe0f","🏃🏼‍♂️":"1f3c3-1f3fc-200d-2642-fe0f","🏃🏽‍♂️":"1f3c3-1f3fd-200d-2642-fe0f","🏃🏾‍♂️":"1f3c3-1f3fe-200d-2642-fe0f","🏃🏿‍♂️":"1f3c3-1f3ff-200d-2642-fe0f","🏃🏻‍♀️":"1f3c3-1f3fb-200d-2640-fe0f","🏃🏼‍♀️":"1f3c3-1f3fc-200d-2640-fe0f","🏃🏽‍♀️":"1f3c3-1f3fd-200d-2640-fe0f","🏃🏾‍♀️":"1f3c3-1f3fe-200d-2640-fe0f","🏃🏿‍♀️":"1f3c3-1f3ff-200d-2640-fe0f","🧖🏻‍♀️":"1f9d6-1f3fb-200d-2640-fe0f","🧖🏼‍♀️":"1f9d6-1f3fc-200d-2640-fe0f","🧖🏽‍♀️":"1f9d6-1f3fd-200d-2640-fe0f","🧖🏾‍♀️":"1f9d6-1f3fe-200d-2640-fe0f","🧖🏿‍♀️":"1f9d6-1f3ff-200d-2640-fe0f","🧖🏻‍♂️":"1f9d6-1f3fb-200d-2642-fe0f","🧖🏼‍♂️":"1f9d6-1f3fc-200d-2642-fe0f","🧖🏽‍♂️":"1f9d6-1f3fd-200d-2642-fe0f","🧖🏾‍♂️":"1f9d6-1f3fe-200d-2642-fe0f","🧖🏿‍♂️":"1f9d6-1f3ff-200d-2642-fe0f","🧗🏻‍♀️":"1f9d7-1f3fb-200d-2640-fe0f","🧗🏼‍♀️":"1f9d7-1f3fc-200d-2640-fe0f","🧗🏽‍♀️":"1f9d7-1f3fd-200d-2640-fe0f","🧗🏾‍♀️":"1f9d7-1f3fe-200d-2640-fe0f","🧗🏿‍♀️":"1f9d7-1f3ff-200d-2640-fe0f","🧗🏻‍♂️":"1f9d7-1f3fb-200d-2642-fe0f","🧗🏼‍♂️":"1f9d7-1f3fc-200d-2642-fe0f","🧗🏽‍♂️":"1f9d7-1f3fd-200d-2642-fe0f","🧗🏾‍♂️":"1f9d7-1f3fe-200d-2642-fe0f","🧗🏿‍♂️":"1f9d7-1f3ff-200d-2642-fe0f","🧘🏻‍♀️":"1f9d8-1f3fb-200d-2640-fe0f","🧘🏼‍♀️":"1f9d8-1f3fc-200d-2640-fe0f","🧘🏽‍♀️":"1f9d8-1f3fd-200d-2640-fe0f","🧘🏾‍♀️":"1f9d8-1f3fe-200d-2640-fe0f","🧘🏿‍♀️":"1f9d8-1f3ff-200d-2640-fe0f","🧘🏻‍♂️":"1f9d8-1f3fb-200d-2642-fe0f","🧘🏼‍♂️":"1f9d8-1f3fc-200d-2642-fe0f","🧘🏽‍♂️":"1f9d8-1f3fd-200d-2642-fe0f","🧘🏾‍♂️":"1f9d8-1f3fe-200d-2642-fe0f","🧘🏿‍♂️":"1f9d8-1f3ff-200d-2642-fe0f","🏌️‍♂️":"1f3cc-fe0f-200d-2642-fe0f","🏌🏻‍♂️":"1f3cc-1f3fb-200d-2642-fe0f","🏌🏼‍♂️":"1f3cc-1f3fc-200d-2642-fe0f","🏌🏽‍♂️":"1f3cc-1f3fd-200d-2642-fe0f","🏌🏾‍♂️":"1f3cc-1f3fe-200d-2642-fe0f","🏌🏿‍♂️":"1f3cc-1f3ff-200d-2642-fe0f","🏌️‍♀️":"1f3cc-fe0f-200d-2640-fe0f","🏌🏻‍♀️":"1f3cc-1f3fb-200d-2640-fe0f","🏌🏼‍♀️":"1f3cc-1f3fc-200d-2640-fe0f","🏌🏽‍♀️":"1f3cc-1f3fd-200d-2640-fe0f","🏌🏾‍♀️":"1f3cc-1f3fe-200d-2640-fe0f","🏌🏿‍♀️":"1f3cc-1f3ff-200d-2640-fe0f","🏄🏻‍♂️":"1f3c4-1f3fb-200d-2642-fe0f","🏄🏼‍♂️":"1f3c4-1f3fc-200d-2642-fe0f","🏄🏽‍♂️":"1f3c4-1f3fd-200d-2642-fe0f","🏄🏾‍♂️":"1f3c4-1f3fe-200d-2642-fe0f","🏄🏿‍♂️":"1f3c4-1f3ff-200d-2642-fe0f","🏄🏻‍♀️":"1f3c4-1f3fb-200d-2640-fe0f","🏄🏼‍♀️":"1f3c4-1f3fc-200d-2640-fe0f","🏄🏽‍♀️":"1f3c4-1f3fd-200d-2640-fe0f","🏄🏾‍♀️":"1f3c4-1f3fe-200d-2640-fe0f","🏄🏿‍♀️":"1f3c4-1f3ff-200d-2640-fe0f","🚣🏻‍♂️":"1f6a3-1f3fb-200d-2642-fe0f","🚣🏼‍♂️":"1f6a3-1f3fc-200d-2642-fe0f","🚣🏽‍♂️":"1f6a3-1f3fd-200d-2642-fe0f","🚣🏾‍♂️":"1f6a3-1f3fe-200d-2642-fe0f","🚣🏿‍♂️":"1f6a3-1f3ff-200d-2642-fe0f","🚣🏻‍♀️":"1f6a3-1f3fb-200d-2640-fe0f","🚣🏼‍♀️":"1f6a3-1f3fc-200d-2640-fe0f","🚣🏽‍♀️":"1f6a3-1f3fd-200d-2640-fe0f","🚣🏾‍♀️":"1f6a3-1f3fe-200d-2640-fe0f","🚣🏿‍♀️":"1f6a3-1f3ff-200d-2640-fe0f","🏊🏻‍♂️":"1f3ca-1f3fb-200d-2642-fe0f","🏊🏼‍♂️":"1f3ca-1f3fc-200d-2642-fe0f","🏊🏽‍♂️":"1f3ca-1f3fd-200d-2642-fe0f","🏊🏾‍♂️":"1f3ca-1f3fe-200d-2642-fe0f","🏊🏿‍♂️":"1f3ca-1f3ff-200d-2642-fe0f","🏊🏻‍♀️":"1f3ca-1f3fb-200d-2640-fe0f","🏊🏼‍♀️":"1f3ca-1f3fc-200d-2640-fe0f","🏊🏽‍♀️":"1f3ca-1f3fd-200d-2640-fe0f","🏊🏾‍♀️":"1f3ca-1f3fe-200d-2640-fe0f","🏊🏿‍♀️":"1f3ca-1f3ff-200d-2640-fe0f","⛹️‍♂️":"26f9-fe0f-200d-2642-fe0f","⛹🏻‍♂️":"26f9-1f3fb-200d-2642-fe0f","⛹🏼‍♂️":"26f9-1f3fc-200d-2642-fe0f","⛹🏽‍♂️":"26f9-1f3fd-200d-2642-fe0f","⛹🏾‍♂️":"26f9-1f3fe-200d-2642-fe0f","⛹🏿‍♂️":"26f9-1f3ff-200d-2642-fe0f","⛹️‍♀️":"26f9-fe0f-200d-2640-fe0f","⛹🏻‍♀️":"26f9-1f3fb-200d-2640-fe0f","⛹🏼‍♀️":"26f9-1f3fc-200d-2640-fe0f","⛹🏽‍♀️":"26f9-1f3fd-200d-2640-fe0f","⛹🏾‍♀️":"26f9-1f3fe-200d-2640-fe0f","⛹🏿‍♀️":"26f9-1f3ff-200d-2640-fe0f","🏋️‍♂️":"1f3cb-fe0f-200d-2642-fe0f","🏋🏻‍♂️":"1f3cb-1f3fb-200d-2642-fe0f","🏋🏼‍♂️":"1f3cb-1f3fc-200d-2642-fe0f","🏋🏽‍♂️":"1f3cb-1f3fd-200d-2642-fe0f","🏋🏾‍♂️":"1f3cb-1f3fe-200d-2642-fe0f","🏋🏿‍♂️":"1f3cb-1f3ff-200d-2642-fe0f","🏋️‍♀️":"1f3cb-fe0f-200d-2640-fe0f","🏋🏻‍♀️":"1f3cb-1f3fb-200d-2640-fe0f","🏋🏼‍♀️":"1f3cb-1f3fc-200d-2640-fe0f","🏋🏽‍♀️":"1f3cb-1f3fd-200d-2640-fe0f","🏋🏾‍♀️":"1f3cb-1f3fe-200d-2640-fe0f","🏋🏿‍♀️":"1f3cb-1f3ff-200d-2640-fe0f","🚴🏻‍♂️":"1f6b4-1f3fb-200d-2642-fe0f","🚴🏼‍♂️":"1f6b4-1f3fc-200d-2642-fe0f","🚴🏽‍♂️":"1f6b4-1f3fd-200d-2642-fe0f","🚴🏾‍♂️":"1f6b4-1f3fe-200d-2642-fe0f","🚴🏿‍♂️":"1f6b4-1f3ff-200d-2642-fe0f","🚴🏻‍♀️":"1f6b4-1f3fb-200d-2640-fe0f","🚴🏼‍♀️":"1f6b4-1f3fc-200d-2640-fe0f","🚴🏽‍♀️":"1f6b4-1f3fd-200d-2640-fe0f","🚴🏾‍♀️":"1f6b4-1f3fe-200d-2640-fe0f","🚴🏿‍♀️":"1f6b4-1f3ff-200d-2640-fe0f","🚵🏻‍♂️":"1f6b5-1f3fb-200d-2642-fe0f","🚵🏼‍♂️":"1f6b5-1f3fc-200d-2642-fe0f","🚵🏽‍♂️":"1f6b5-1f3fd-200d-2642-fe0f","🚵🏾‍♂️":"1f6b5-1f3fe-200d-2642-fe0f","🚵🏿‍♂️":"1f6b5-1f3ff-200d-2642-fe0f","🚵🏻‍♀️":"1f6b5-1f3fb-200d-2640-fe0f","🚵🏼‍♀️":"1f6b5-1f3fc-200d-2640-fe0f","🚵🏽‍♀️":"1f6b5-1f3fd-200d-2640-fe0f","🚵🏾‍♀️":"1f6b5-1f3fe-200d-2640-fe0f","🚵🏿‍♀️":"1f6b5-1f3ff-200d-2640-fe0f","🤸🏻‍♂️":"1f938-1f3fb-200d-2642-fe0f","🤸🏼‍♂️":"1f938-1f3fc-200d-2642-fe0f","🤸🏽‍♂️":"1f938-1f3fd-200d-2642-fe0f","🤸🏾‍♂️":"1f938-1f3fe-200d-2642-fe0f","🤸🏿‍♂️":"1f938-1f3ff-200d-2642-fe0f","🤸🏻‍♀️":"1f938-1f3fb-200d-2640-fe0f","🤸🏼‍♀️":"1f938-1f3fc-200d-2640-fe0f","🤸🏽‍♀️":"1f938-1f3fd-200d-2640-fe0f","🤸🏾‍♀️":"1f938-1f3fe-200d-2640-fe0f","🤸🏿‍♀️":"1f938-1f3ff-200d-2640-fe0f","🤽🏻‍♂️":"1f93d-1f3fb-200d-2642-fe0f","🤽🏼‍♂️":"1f93d-1f3fc-200d-2642-fe0f","🤽🏽‍♂️":"1f93d-1f3fd-200d-2642-fe0f","🤽🏾‍♂️":"1f93d-1f3fe-200d-2642-fe0f","🤽🏿‍♂️":"1f93d-1f3ff-200d-2642-fe0f","🤽🏻‍♀️":"1f93d-1f3fb-200d-2640-fe0f","🤽🏼‍♀️":"1f93d-1f3fc-200d-2640-fe0f","🤽🏽‍♀️":"1f93d-1f3fd-200d-2640-fe0f","🤽🏾‍♀️":"1f93d-1f3fe-200d-2640-fe0f","🤽🏿‍♀️":"1f93d-1f3ff-200d-2640-fe0f","🤾🏻‍♂️":"1f93e-1f3fb-200d-2642-fe0f","🤾🏼‍♂️":"1f93e-1f3fc-200d-2642-fe0f","🤾🏽‍♂️":"1f93e-1f3fd-200d-2642-fe0f","🤾🏾‍♂️":"1f93e-1f3fe-200d-2642-fe0f","🤾🏿‍♂️":"1f93e-1f3ff-200d-2642-fe0f","🤾🏻‍♀️":"1f93e-1f3fb-200d-2640-fe0f","🤾🏼‍♀️":"1f93e-1f3fc-200d-2640-fe0f","🤾🏽‍♀️":"1f93e-1f3fd-200d-2640-fe0f","🤾🏾‍♀️":"1f93e-1f3fe-200d-2640-fe0f","🤾🏿‍♀️":"1f93e-1f3ff-200d-2640-fe0f","🤹🏻‍♂️":"1f939-1f3fb-200d-2642-fe0f","🤹🏼‍♂️":"1f939-1f3fc-200d-2642-fe0f","🤹🏽‍♂️":"1f939-1f3fd-200d-2642-fe0f","🤹🏾‍♂️":"1f939-1f3fe-200d-2642-fe0f","🤹🏿‍♂️":"1f939-1f3ff-200d-2642-fe0f","🤹🏻‍♀️":"1f939-1f3fb-200d-2640-fe0f","🤹🏼‍♀️":"1f939-1f3fc-200d-2640-fe0f","🤹🏽‍♀️":"1f939-1f3fd-200d-2640-fe0f","🤹🏾‍♀️":"1f939-1f3fe-200d-2640-fe0f","🤹🏿‍♀️":"1f939-1f3ff-200d-2640-fe0f","👩‍❤‍👨":"1f469-200d-2764-fe0f-200d-1f468","👨‍❤‍👨":"1f468-200d-2764-fe0f-200d-1f468","👩‍❤‍👩":"1f469-200d-2764-fe0f-200d-1f469","👨‍👩‍👦":"1f468-200d-1f469-200d-1f466","👨‍👩‍👧":"1f468-200d-1f469-200d-1f467","👨‍👨‍👦":"1f468-200d-1f468-200d-1f466","👨‍👨‍👧":"1f468-200d-1f468-200d-1f467","👩‍👩‍👦":"1f469-200d-1f469-200d-1f466","👩‍👩‍👧":"1f469-200d-1f469-200d-1f467","👨‍👦‍👦":"1f468-200d-1f466-200d-1f466","👨‍👧‍👦":"1f468-200d-1f467-200d-1f466","👨‍👧‍👧":"1f468-200d-1f467-200d-1f467","👩‍👦‍👦":"1f469-200d-1f466-200d-1f466","👩‍👧‍👦":"1f469-200d-1f467-200d-1f466","👩‍👧‍👧":"1f469-200d-1f467-200d-1f467","👁️‍🗨️":"1f441-200d-1f5e8","👩‍❤️‍👨":"1f469-200d-2764-fe0f-200d-1f468","👨‍❤️‍👨":"1f468-200d-2764-fe0f-200d-1f468","👩‍❤️‍👩":"1f469-200d-2764-fe0f-200d-1f469","👩‍❤‍💋‍👨":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","👨‍❤‍💋‍👨":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","👩‍❤‍💋‍👩":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469","👨‍👩‍👧‍👦":"1f468-200d-1f469-200d-1f467-200d-1f466","👨‍👩‍👦‍👦":"1f468-200d-1f469-200d-1f466-200d-1f466","👨‍👩‍👧‍👧":"1f468-200d-1f469-200d-1f467-200d-1f467","👨‍👨‍👧‍👦":"1f468-200d-1f468-200d-1f467-200d-1f466","👨‍👨‍👦‍👦":"1f468-200d-1f468-200d-1f466-200d-1f466","👨‍👨‍👧‍👧":"1f468-200d-1f468-200d-1f467-200d-1f467","👩‍👩‍👧‍👦":"1f469-200d-1f469-200d-1f467-200d-1f466","👩‍👩‍👦‍👦":"1f469-200d-1f469-200d-1f466-200d-1f466","👩‍👩‍👧‍👧":"1f469-200d-1f469-200d-1f467-200d-1f467","🏴󠁧󠁢󠁥󠁮󠁧󠁿":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f","🏴󠁧󠁢󠁳󠁣󠁴󠁿":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f","🏴󠁧󠁢󠁷󠁬󠁳󠁿":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f","👩‍❤️‍💋‍👨":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","👨‍❤️‍💋‍👨":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","👩‍❤️‍💋‍👩":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469"}
\ No newline at end of file
+{"😀":"1f600","😁":"1f601","😂":"1f602","🤣":"1f923","😃":"1f603","😄":"1f604","😅":"1f605","😆":"1f606","😉":"1f609","😊":"1f60a","😋":"1f60b","😎":"1f60e","😍":"1f60d","😘":"1f618","🥰":"1f970","😗":"1f617","😙":"1f619","😚":"1f61a","☺":"263a","🙂":"1f642","🤗":"1f917","🤩":"1f929","🤔":"1f914","🤨":"1f928","😐":"1f610","😑":"1f611","😶":"1f636","🙄":"1f644","😏":"1f60f","😣":"1f623","😥":"1f625","😮":"1f62e","🤐":"1f910","😯":"1f62f","😪":"1f62a","😫":"1f62b","😴":"1f634","😌":"1f60c","😛":"1f61b","😜":"1f61c","😝":"1f61d","🤤":"1f924","😒":"1f612","😓":"1f613","😔":"1f614","😕":"1f615","🙃":"1f643","🤑":"1f911","😲":"1f632","☹":"2639","🙁":"1f641","😖":"1f616","😞":"1f61e","😟":"1f61f","😤":"1f624","😢":"1f622","😭":"1f62d","😦":"1f626","😧":"1f627","😨":"1f628","😩":"1f629","🤯":"1f92f","😬":"1f62c","😰":"1f630","😱":"1f631","🥵":"1f975","🥶":"1f976","😳":"1f633","🤪":"1f92a","😵":"1f635","😡":"1f621","😠":"1f620","🤬":"1f92c","😷":"1f637","🤒":"1f912","🤕":"1f915","🤢":"1f922","🤮":"1f92e","🤧":"1f927","😇":"1f607","🤠":"1f920","🥳":"1f973","🥴":"1f974","🥺":"1f97a","🤥":"1f925","🤫":"1f92b","🤭":"1f92d","🧐":"1f9d0","🤓":"1f913","😈":"1f608","👿":"1f47f","🤡":"1f921","👹":"1f479","👺":"1f47a","💀":"1f480","☠":"2620","👻":"1f47b","👽":"1f47d","👾":"1f47e","🤖":"1f916","💩":"1f4a9","😺":"1f63a","😸":"1f638","😹":"1f639","😻":"1f63b","😼":"1f63c","😽":"1f63d","🙀":"1f640","😿":"1f63f","😾":"1f63e","🙈":"1f648","🙉":"1f649","🙊":"1f64a","🏻":"1f3fb","🏼":"1f3fc","🏽":"1f3fd","🏾":"1f3fe","🏿":"1f3ff","👶":"1f476","🧒":"1f9d2","👦":"1f466","👧":"1f467","🧑":"1f9d1","👨":"1f468","👩":"1f469","🧓":"1f9d3","👴":"1f474","👵":"1f475","👮":"1f46e","🕵":"1f575","💂":"1f482","👷":"1f477","🤴":"1f934","👸":"1f478","👳":"1f473","👲":"1f472","🧕":"1f9d5","🧔":"1f9d4","👱":"1f471","🤵":"1f935","👰":"1f470","🤰":"1f930","🤱":"1f931","👼":"1f47c","🎅":"1f385","🤶":"1f936","🦸":"1f9b8","🦹":"1f9b9","🧙":"1f9d9","🧚":"1f9da","🧛":"1f9db","🧜":"1f9dc","🧝":"1f9dd","🧞":"1f9de","🧟":"1f9df","🙍":"1f64d","🙎":"1f64e","🙅":"1f645","🙆":"1f646","💁":"1f481","🙋":"1f64b","🙇":"1f647","🤦":"1f926","🤷":"1f937","💆":"1f486","💇":"1f487","🚶":"1f6b6","🏃":"1f3c3","💃":"1f483","🕺":"1f57a","👯":"1f46f","🧖":"1f9d6","🧗":"1f9d7","🧘":"1f9d8","🛀":"1f6c0","🛌":"1f6cc","🕴":"1f574","🗣":"1f5e3","👤":"1f464","👥":"1f465","🤺":"1f93a","🏇":"1f3c7","⛷":"26f7","🏂":"1f3c2","🏌":"1f3cc","🏄":"1f3c4","🚣":"1f6a3","🏊":"1f3ca","⛹":"26f9","🏋":"1f3cb","🚴":"1f6b4","🚵":"1f6b5","🏎":"1f3ce","🏍":"1f3cd","🤸":"1f938","🤼":"1f93c","🤽":"1f93d","🤾":"1f93e","🤹":"1f939","👫":"1f46b","👬":"1f46c","👭":"1f46d","💏":"1f48f","💑":"1f491","👪":"1f46a","🤳":"1f933","💪":"1f4aa","🦵":"1f9b5","🦶":"1f9b6","👈":"1f448","👉":"1f449","☝":"261d","👆":"1f446","🖕":"1f595","👇":"1f447","✌":"270c","🤞":"1f91e","🖖":"1f596","🤘":"1f918","🤙":"1f919","🖐":"1f590","✋":"270b","👌":"1f44c","👍":"1f44d","👎":"1f44e","✊":"270a","👊":"1f44a","🤛":"1f91b","🤜":"1f91c","🤚":"1f91a","👋":"1f44b","🤟":"1f91f","✍":"270d","👏":"1f44f","👐":"1f450","🙌":"1f64c","🤲":"1f932","🙏":"1f64f","🤝":"1f91d","💅":"1f485","👂":"1f442","👃":"1f443","👣":"1f463","👀":"1f440","👁":"1f441","🧠":"1f9e0","🦴":"1f9b4","🦷":"1f9b7","👅":"1f445","👄":"1f444","💋":"1f48b","💘":"1f498","❤":"2764","💓":"1f493","💔":"1f494","💕":"1f495","💖":"1f496","💗":"1f497","💙":"1f499","💚":"1f49a","💛":"1f49b","🧡":"1f9e1","💜":"1f49c","🖤":"1f5a4","💝":"1f49d","💞":"1f49e","💟":"1f49f","❣":"2763","💌":"1f48c","💤":"1f4a4","💢":"1f4a2","💣":"1f4a3","💥":"1f4a5","💦":"1f4a6","💨":"1f4a8","💫":"1f4ab","💬":"1f4ac","🗨":"1f5e8","🗯":"1f5ef","💭":"1f4ad","🕳":"1f573","👓":"1f453","🕶":"1f576","🥽":"1f97d","🥼":"1f97c","👔":"1f454","👕":"1f455","👖":"1f456","🧣":"1f9e3","🧤":"1f9e4","🧥":"1f9e5","🧦":"1f9e6","👗":"1f457","👘":"1f458","👙":"1f459","👚":"1f45a","👛":"1f45b","👜":"1f45c","👝":"1f45d","🛍":"1f6cd","🎒":"1f392","👞":"1f45e","👟":"1f45f","🥾":"1f97e","🥿":"1f97f","👠":"1f460","👡":"1f461","👢":"1f462","👑":"1f451","👒":"1f452","🎩":"1f3a9","🎓":"1f393","🧢":"1f9e2","⛑":"26d1","📿":"1f4ff","💄":"1f484","💍":"1f48d","💎":"1f48e","🐵":"1f435","🐒":"1f412","🦍":"1f98d","🐶":"1f436","🐕":"1f415","🐩":"1f429","🐺":"1f43a","🦊":"1f98a","🦝":"1f99d","🐱":"1f431","🐈":"1f408","🦁":"1f981","🐯":"1f42f","🐅":"1f405","🐆":"1f406","🐴":"1f434","🐎":"1f40e","🦄":"1f984","🦓":"1f993","🦌":"1f98c","🐮":"1f42e","🐂":"1f402","🐃":"1f403","🐄":"1f404","🐷":"1f437","🐖":"1f416","🐗":"1f417","🐽":"1f43d","🐏":"1f40f","🐑":"1f411","🐐":"1f410","🐪":"1f42a","🐫":"1f42b","🦙":"1f999","🦒":"1f992","🐘":"1f418","🦏":"1f98f","🦛":"1f99b","🐭":"1f42d","🐁":"1f401","🐀":"1f400","🐹":"1f439","🐰":"1f430","🐇":"1f407","🐿":"1f43f","🦔":"1f994","🦇":"1f987","🐻":"1f43b","🐨":"1f428","🐼":"1f43c","🦘":"1f998","🦡":"1f9a1","🐾":"1f43e","🦃":"1f983","🐔":"1f414","🐓":"1f413","🐣":"1f423","🐤":"1f424","🐥":"1f425","🐦":"1f426","🐧":"1f427","🕊":"1f54a","🦅":"1f985","🦆":"1f986","🦢":"1f9a2","🦉":"1f989","🦚":"1f99a","🦜":"1f99c","🐸":"1f438","🐊":"1f40a","🐢":"1f422","🦎":"1f98e","🐍":"1f40d","🐲":"1f432","🐉":"1f409","🦕":"1f995","🦖":"1f996","🐳":"1f433","🐋":"1f40b","🐬":"1f42c","🐟":"1f41f","🐠":"1f420","🐡":"1f421","🦈":"1f988","🐙":"1f419","🐚":"1f41a","🦀":"1f980","🦞":"1f99e","🦐":"1f990","🦑":"1f991","🐌":"1f40c","🦋":"1f98b","🐛":"1f41b","🐜":"1f41c","🐝":"1f41d","🐞":"1f41e","🦗":"1f997","🕷":"1f577","🕸":"1f578","🦂":"1f982","🦟":"1f99f","🦠":"1f9a0","💐":"1f490","🌸":"1f338","💮":"1f4ae","🏵":"1f3f5","🌹":"1f339","🥀":"1f940","🌺":"1f33a","🌻":"1f33b","🌼":"1f33c","🌷":"1f337","🌱":"1f331","🌲":"1f332","🌳":"1f333","🌴":"1f334","🌵":"1f335","🌾":"1f33e","🌿":"1f33f","☘":"2618","🍀":"1f340","🍁":"1f341","🍂":"1f342","🍃":"1f343","🍇":"1f347","🍈":"1f348","🍉":"1f349","🍊":"1f34a","🍋":"1f34b","🍌":"1f34c","🍍":"1f34d","🥭":"1f96d","🍎":"1f34e","🍏":"1f34f","🍐":"1f350","🍑":"1f351","🍒":"1f352","🍓":"1f353","🥝":"1f95d","🍅":"1f345","🥥":"1f965","🥑":"1f951","🍆":"1f346","🥔":"1f954","🥕":"1f955","🌽":"1f33d","🌶":"1f336","🥒":"1f952","🥬":"1f96c","🥦":"1f966","🍄":"1f344","🥜":"1f95c","🌰":"1f330","🍞":"1f35e","🥐":"1f950","🥖":"1f956","🥨":"1f968","🥯":"1f96f","🥞":"1f95e","🧀":"1f9c0","🍖":"1f356","🍗":"1f357","🥩":"1f969","🥓":"1f953","🍔":"1f354","🍟":"1f35f","🍕":"1f355","🌭":"1f32d","🥪":"1f96a","🌮":"1f32e","🌯":"1f32f","🥙":"1f959","🥚":"1f95a","🍳":"1f373","🥘":"1f958","🍲":"1f372","🥣":"1f963","🥗":"1f957","🍿":"1f37f","🧂":"1f9c2","🥫":"1f96b","🍱":"1f371","🍘":"1f358","🍙":"1f359","🍚":"1f35a","🍛":"1f35b","🍜":"1f35c","🍝":"1f35d","🍠":"1f360","🍢":"1f362","🍣":"1f363","🍤":"1f364","🍥":"1f365","🥮":"1f96e","🍡":"1f361","🥟":"1f95f","🥠":"1f960","🥡":"1f961","🍦":"1f366","🍧":"1f367","🍨":"1f368","🍩":"1f369","🍪":"1f36a","🎂":"1f382","🍰":"1f370","🧁":"1f9c1","🥧":"1f967","🍫":"1f36b","🍬":"1f36c","🍭":"1f36d","🍮":"1f36e","🍯":"1f36f","🍼":"1f37c","🥛":"1f95b","☕":"2615","🍵":"1f375","🍶":"1f376","🍾":"1f37e","🍷":"1f377","🍸":"1f378","🍹":"1f379","🍺":"1f37a","🍻":"1f37b","🥂":"1f942","🥃":"1f943","🥤":"1f964","🥢":"1f962","🍽":"1f37d","🍴":"1f374","🥄":"1f944","🔪":"1f52a","🏺":"1f3fa","🌍":"1f30d","🌎":"1f30e","🌏":"1f30f","🌐":"1f310","🗺":"1f5fa","🗾":"1f5fe","🧭":"1f9ed","🏔":"1f3d4","⛰":"26f0","🌋":"1f30b","🗻":"1f5fb","🏕":"1f3d5","🏖":"1f3d6","🏜":"1f3dc","🏝":"1f3dd","🏞":"1f3de","🏟":"1f3df","🏛":"1f3db","🏗":"1f3d7","🧱":"1f9f1","🏘":"1f3d8","🏚":"1f3da","🏠":"1f3e0","🏡":"1f3e1","🏢":"1f3e2","🏣":"1f3e3","🏤":"1f3e4","🏥":"1f3e5","🏦":"1f3e6","🏨":"1f3e8","🏩":"1f3e9","🏪":"1f3ea","🏫":"1f3eb","🏬":"1f3ec","🏭":"1f3ed","🏯":"1f3ef","🏰":"1f3f0","💒":"1f492","🗼":"1f5fc","🗽":"1f5fd","⛪":"26ea","🕌":"1f54c","🕍":"1f54d","⛩":"26e9","🕋":"1f54b","⛲":"26f2","⛺":"26fa","🌁":"1f301","🌃":"1f303","🏙":"1f3d9","🌄":"1f304","🌅":"1f305","🌆":"1f306","🌇":"1f307","🌉":"1f309","♨":"2668","🌌":"1f30c","🎠":"1f3a0","🎡":"1f3a1","🎢":"1f3a2","💈":"1f488","🎪":"1f3aa","🚂":"1f682","🚃":"1f683","🚄":"1f684","🚅":"1f685","🚆":"1f686","🚇":"1f687","🚈":"1f688","🚉":"1f689","🚊":"1f68a","🚝":"1f69d","🚞":"1f69e","🚋":"1f68b","🚌":"1f68c","🚍":"1f68d","🚎":"1f68e","🚐":"1f690","🚑":"1f691","🚒":"1f692","🚓":"1f693","🚔":"1f694","🚕":"1f695","🚖":"1f696","🚗":"1f697","🚘":"1f698","🚙":"1f699","🚚":"1f69a","🚛":"1f69b","🚜":"1f69c","🚲":"1f6b2","🛴":"1f6f4","🛹":"1f6f9","🛵":"1f6f5","🚏":"1f68f","🛣":"1f6e3","🛤":"1f6e4","🛢":"1f6e2","⛽":"26fd","🚨":"1f6a8","🚥":"1f6a5","🚦":"1f6a6","🛑":"1f6d1","🚧":"1f6a7","⚓":"2693","⛵":"26f5","🛶":"1f6f6","🚤":"1f6a4","🛳":"1f6f3","⛴":"26f4","🛥":"1f6e5","🚢":"1f6a2","✈":"2708","🛩":"1f6e9","🛫":"1f6eb","🛬":"1f6ec","💺":"1f4ba","🚁":"1f681","🚟":"1f69f","🚠":"1f6a0","🚡":"1f6a1","🛰":"1f6f0","🚀":"1f680","🛸":"1f6f8","🛎":"1f6ce","🧳":"1f9f3","⌛":"231b","⏳":"23f3","⌚":"231a","⏰":"23f0","⏱":"23f1","⏲":"23f2","🕰":"1f570","🕛":"1f55b","🕧":"1f567","🕐":"1f550","🕜":"1f55c","🕑":"1f551","🕝":"1f55d","🕒":"1f552","🕞":"1f55e","🕓":"1f553","🕟":"1f55f","🕔":"1f554","🕠":"1f560","🕕":"1f555","🕡":"1f561","🕖":"1f556","🕢":"1f562","🕗":"1f557","🕣":"1f563","🕘":"1f558","🕤":"1f564","🕙":"1f559","🕥":"1f565","🕚":"1f55a","🕦":"1f566","🌑":"1f311","🌒":"1f312","🌓":"1f313","🌔":"1f314","🌕":"1f315","🌖":"1f316","🌗":"1f317","🌘":"1f318","🌙":"1f319","🌚":"1f31a","🌛":"1f31b","🌜":"1f31c","🌡":"1f321","☀":"2600","🌝":"1f31d","🌞":"1f31e","⭐":"2b50","🌟":"1f31f","🌠":"1f320","☁":"2601","⛅":"26c5","⛈":"26c8","🌤":"1f324","🌥":"1f325","🌦":"1f326","🌧":"1f327","🌨":"1f328","🌩":"1f329","🌪":"1f32a","🌫":"1f32b","🌬":"1f32c","🌀":"1f300","🌈":"1f308","🌂":"1f302","☂":"2602","☔":"2614","⛱":"26f1","⚡":"26a1","❄":"2744","☃":"2603","⛄":"26c4","☄":"2604","🔥":"1f525","💧":"1f4a7","🌊":"1f30a","🎃":"1f383","🎄":"1f384","🎆":"1f386","🎇":"1f387","🧨":"1f9e8","✨":"2728","🎈":"1f388","🎉":"1f389","🎊":"1f38a","🎋":"1f38b","🎍":"1f38d","🎎":"1f38e","🎏":"1f38f","🎐":"1f390","🎑":"1f391","🧧":"1f9e7","🎀":"1f380","🎁":"1f381","🎗":"1f397","🎟":"1f39f","🎫":"1f3ab","🎖":"1f396","🏆":"1f3c6","🏅":"1f3c5","🥇":"1f947","🥈":"1f948","🥉":"1f949","⚽":"26bd","⚾":"26be","🥎":"1f94e","🏀":"1f3c0","🏐":"1f3d0","🏈":"1f3c8","🏉":"1f3c9","🎾":"1f3be","🥏":"1f94f","🎳":"1f3b3","🏏":"1f3cf","🏑":"1f3d1","🏒":"1f3d2","🥍":"1f94d","🏓":"1f3d3","🏸":"1f3f8","🥊":"1f94a","🥋":"1f94b","🥅":"1f945","⛳":"26f3","⛸":"26f8","🎣":"1f3a3","🎽":"1f3bd","🎿":"1f3bf","🛷":"1f6f7","🥌":"1f94c","🎯":"1f3af","🎱":"1f3b1","🔮":"1f52e","🧿":"1f9ff","🎮":"1f3ae","🕹":"1f579","🎰":"1f3b0","🎲":"1f3b2","🧩":"1f9e9","🧸":"1f9f8","♠":"2660","♥":"2665","♦":"2666","♣":"2663","♟":"265f","🃏":"1f0cf","🀄":"1f004","🎴":"1f3b4","🎭":"1f3ad","🖼":"1f5bc","🎨":"1f3a8","🧵":"1f9f5","🧶":"1f9f6","🔇":"1f507","🔈":"1f508","🔉":"1f509","🔊":"1f50a","📢":"1f4e2","📣":"1f4e3","📯":"1f4ef","🔔":"1f514","🔕":"1f515","🎼":"1f3bc","🎵":"1f3b5","🎶":"1f3b6","🎙":"1f399","🎚":"1f39a","🎛":"1f39b","🎤":"1f3a4","🎧":"1f3a7","📻":"1f4fb","🎷":"1f3b7","🎸":"1f3b8","🎹":"1f3b9","🎺":"1f3ba","🎻":"1f3bb","🥁":"1f941","📱":"1f4f1","📲":"1f4f2","☎":"260e","📞":"1f4de","📟":"1f4df","📠":"1f4e0","🔋":"1f50b","🔌":"1f50c","💻":"1f4bb","🖥":"1f5a5","🖨":"1f5a8","⌨":"2328","🖱":"1f5b1","🖲":"1f5b2","💽":"1f4bd","💾":"1f4be","💿":"1f4bf","📀":"1f4c0","🧮":"1f9ee","🎥":"1f3a5","🎞":"1f39e","📽":"1f4fd","🎬":"1f3ac","📺":"1f4fa","📷":"1f4f7","📸":"1f4f8","📹":"1f4f9","📼":"1f4fc","🔍":"1f50d","🔎":"1f50e","🕯":"1f56f","💡":"1f4a1","🔦":"1f526","🏮":"1f3ee","📔":"1f4d4","📕":"1f4d5","📖":"1f4d6","📗":"1f4d7","📘":"1f4d8","📙":"1f4d9","📚":"1f4da","📓":"1f4d3","📒":"1f4d2","📃":"1f4c3","📜":"1f4dc","📄":"1f4c4","📰":"1f4f0","🗞":"1f5de","📑":"1f4d1","🔖":"1f516","🏷":"1f3f7","💰":"1f4b0","💴":"1f4b4","💵":"1f4b5","💶":"1f4b6","💷":"1f4b7","💸":"1f4b8","💳":"1f4b3","🧾":"1f9fe","💹":"1f4b9","💱":"1f4b1","💲":"1f4b2","✉":"2709","📧":"1f4e7","📨":"1f4e8","📩":"1f4e9","📤":"1f4e4","📥":"1f4e5","📦":"1f4e6","📫":"1f4eb","📪":"1f4ea","📬":"1f4ec","📭":"1f4ed","📮":"1f4ee","🗳":"1f5f3","✏":"270f","✒":"2712","🖋":"1f58b","🖊":"1f58a","🖌":"1f58c","🖍":"1f58d","📝":"1f4dd","💼":"1f4bc","📁":"1f4c1","📂":"1f4c2","🗂":"1f5c2","📅":"1f4c5","📆":"1f4c6","🗒":"1f5d2","🗓":"1f5d3","📇":"1f4c7","📈":"1f4c8","📉":"1f4c9","📊":"1f4ca","📋":"1f4cb","📌":"1f4cc","📍":"1f4cd","📎":"1f4ce","🖇":"1f587","📏":"1f4cf","📐":"1f4d0","✂":"2702","🗃":"1f5c3","🗄":"1f5c4","🗑":"1f5d1","🔒":"1f512","🔓":"1f513","🔏":"1f50f","🔐":"1f510","🔑":"1f511","🗝":"1f5dd","🔨":"1f528","⛏":"26cf","⚒":"2692","🛠":"1f6e0","🗡":"1f5e1","⚔":"2694","🔫":"1f52b","🏹":"1f3f9","🛡":"1f6e1","🔧":"1f527","🔩":"1f529","⚙":"2699","🗜":"1f5dc","⚖":"2696","🔗":"1f517","⛓":"26d3","🧰":"1f9f0","🧲":"1f9f2","⚗":"2697","🧪":"1f9ea","🧫":"1f9eb","🧬":"1f9ec","🔬":"1f52c","🔭":"1f52d","📡":"1f4e1","💉":"1f489","💊":"1f48a","🚪":"1f6aa","🛏":"1f6cf","🛋":"1f6cb","🚽":"1f6bd","🚿":"1f6bf","🛁":"1f6c1","🧴":"1f9f4","🧷":"1f9f7","🧹":"1f9f9","🧺":"1f9fa","🧻":"1f9fb","🧼":"1f9fc","🧽":"1f9fd","🧯":"1f9ef","🛒":"1f6d2","🚬":"1f6ac","⚰":"26b0","⚱":"26b1","🗿":"1f5ff","🏧":"1f3e7","🚮":"1f6ae","🚰":"1f6b0","♿":"267f","🚹":"1f6b9","🚺":"1f6ba","🚻":"1f6bb","🚼":"1f6bc","🚾":"1f6be","🛂":"1f6c2","🛃":"1f6c3","🛄":"1f6c4","🛅":"1f6c5","⚠":"26a0","🚸":"1f6b8","⛔":"26d4","🚫":"1f6ab","🚳":"1f6b3","🚭":"1f6ad","🚯":"1f6af","🚱":"1f6b1","🚷":"1f6b7","📵":"1f4f5","🔞":"1f51e","☢":"2622","☣":"2623","⬆":"2b06","↗":"2197","➡":"27a1","↘":"2198","⬇":"2b07","↙":"2199","⬅":"2b05","↖":"2196","↕":"2195","↔":"2194","↩":"21a9","↪":"21aa","⤴":"2934","⤵":"2935","🔃":"1f503","🔄":"1f504","🔙":"1f519","🔚":"1f51a","🔛":"1f51b","🔜":"1f51c","🔝":"1f51d","🛐":"1f6d0","⚛":"269b","🕉":"1f549","✡":"2721","☸":"2638","☯":"262f","✝":"271d","☦":"2626","☪":"262a","☮":"262e","🕎":"1f54e","🔯":"1f52f","♈":"2648","♉":"2649","♊":"264a","♋":"264b","♌":"264c","♍":"264d","♎":"264e","♏":"264f","♐":"2650","♑":"2651","♒":"2652","♓":"2653","⛎":"26ce","🔀":"1f500","🔁":"1f501","🔂":"1f502","▶":"25b6","⏩":"23e9","⏭":"23ed","⏯":"23ef","◀":"25c0","⏪":"23ea","⏮":"23ee","🔼":"1f53c","⏫":"23eb","🔽":"1f53d","⏬":"23ec","⏸":"23f8","⏹":"23f9","⏺":"23fa","⏏":"23cf","🎦":"1f3a6","🔅":"1f505","🔆":"1f506","📶":"1f4f6","📳":"1f4f3","📴":"1f4f4","♀":"2640","♂":"2642","⚕":"2695","♾":"267e","♻":"267b","⚜":"269c","🔱":"1f531","📛":"1f4db","🔰":"1f530","⭕":"2b55","✅":"2705","☑":"2611","✔":"2714","✖":"2716","❌":"274c","❎":"274e","➕":"2795","➖":"2796","➗":"2797","➰":"27b0","➿":"27bf","〽":"303d","✳":"2733","✴":"2734","❇":"2747","‼":"203c","⁉":"2049","❓":"2753","❔":"2754","❕":"2755","❗":"2757","〰":"3030","©":"a9","®":"ae","™":"2122","🔟":"1f51f","💯":"1f4af","🔠":"1f520","🔡":"1f521","🔢":"1f522","🔣":"1f523","🔤":"1f524","🅰":"1f170","🆎":"1f18e","🅱":"1f171","🆑":"1f191","🆒":"1f192","🆓":"1f193","ℹ":"2139","🆔":"1f194","Ⓜ":"24c2","🆕":"1f195","🆖":"1f196","🅾":"1f17e","🆗":"1f197","🅿":"1f17f","🆘":"1f198","🆙":"1f199","🆚":"1f19a","🈁":"1f201","🈂":"1f202","🈷":"1f237","🈶":"1f236","🈯":"1f22f","🉐":"1f250","🈹":"1f239","🈚":"1f21a","🈲":"1f232","🉑":"1f251","🈸":"1f238","🈴":"1f234","🈳":"1f233","㊗":"3297","㊙":"3299","🈺":"1f23a","🈵":"1f235","▪":"25aa","▫":"25ab","◻":"25fb","◼":"25fc","◽":"25fd","◾":"25fe","⬛":"2b1b","⬜":"2b1c","🔶":"1f536","🔷":"1f537","🔸":"1f538","🔹":"1f539","🔺":"1f53a","🔻":"1f53b","💠":"1f4a0","🔘":"1f518","🔲":"1f532","🔳":"1f533","⚪":"26aa","⚫":"26ab","🔴":"1f534","🔵":"1f535","🏁":"1f3c1","🚩":"1f6a9","🎌":"1f38c","🏴":"1f3f4","🏳":"1f3f3","☺️":"263a","☹️":"2639","☠️":"2620","👶🏻":"1f476-1f3fb","👶🏼":"1f476-1f3fc","👶🏽":"1f476-1f3fd","👶🏾":"1f476-1f3fe","👶🏿":"1f476-1f3ff","🧒🏻":"1f9d2-1f3fb","🧒🏼":"1f9d2-1f3fc","🧒🏽":"1f9d2-1f3fd","🧒🏾":"1f9d2-1f3fe","🧒🏿":"1f9d2-1f3ff","👦🏻":"1f466-1f3fb","👦🏼":"1f466-1f3fc","👦🏽":"1f466-1f3fd","👦🏾":"1f466-1f3fe","👦🏿":"1f466-1f3ff","👧🏻":"1f467-1f3fb","👧🏼":"1f467-1f3fc","👧🏽":"1f467-1f3fd","👧🏾":"1f467-1f3fe","👧🏿":"1f467-1f3ff","🧑🏻":"1f9d1-1f3fb","🧑🏼":"1f9d1-1f3fc","🧑🏽":"1f9d1-1f3fd","🧑🏾":"1f9d1-1f3fe","🧑🏿":"1f9d1-1f3ff","👨🏻":"1f468-1f3fb","👨🏼":"1f468-1f3fc","👨🏽":"1f468-1f3fd","👨🏾":"1f468-1f3fe","👨🏿":"1f468-1f3ff","👩🏻":"1f469-1f3fb","👩🏼":"1f469-1f3fc","👩🏽":"1f469-1f3fd","👩🏾":"1f469-1f3fe","👩🏿":"1f469-1f3ff","🧓🏻":"1f9d3-1f3fb","🧓🏼":"1f9d3-1f3fc","🧓🏽":"1f9d3-1f3fd","🧓🏾":"1f9d3-1f3fe","🧓🏿":"1f9d3-1f3ff","👴🏻":"1f474-1f3fb","👴🏼":"1f474-1f3fc","👴🏽":"1f474-1f3fd","👴🏾":"1f474-1f3fe","👴🏿":"1f474-1f3ff","👵🏻":"1f475-1f3fb","👵🏼":"1f475-1f3fc","👵🏽":"1f475-1f3fd","👵🏾":"1f475-1f3fe","👵🏿":"1f475-1f3ff","👮🏻":"1f46e-1f3fb","👮🏼":"1f46e-1f3fc","👮🏽":"1f46e-1f3fd","👮🏾":"1f46e-1f3fe","👮🏿":"1f46e-1f3ff","🕵️":"1f575","🕵🏻":"1f575-1f3fb","🕵🏼":"1f575-1f3fc","🕵🏽":"1f575-1f3fd","🕵🏾":"1f575-1f3fe","🕵🏿":"1f575-1f3ff","💂🏻":"1f482-1f3fb","💂🏼":"1f482-1f3fc","💂🏽":"1f482-1f3fd","💂🏾":"1f482-1f3fe","💂🏿":"1f482-1f3ff","👷🏻":"1f477-1f3fb","👷🏼":"1f477-1f3fc","👷🏽":"1f477-1f3fd","👷🏾":"1f477-1f3fe","👷🏿":"1f477-1f3ff","🤴🏻":"1f934-1f3fb","🤴🏼":"1f934-1f3fc","🤴🏽":"1f934-1f3fd","🤴🏾":"1f934-1f3fe","🤴🏿":"1f934-1f3ff","👸🏻":"1f478-1f3fb","👸🏼":"1f478-1f3fc","👸🏽":"1f478-1f3fd","👸🏾":"1f478-1f3fe","👸🏿":"1f478-1f3ff","👳🏻":"1f473-1f3fb","👳🏼":"1f473-1f3fc","👳🏽":"1f473-1f3fd","👳🏾":"1f473-1f3fe","👳🏿":"1f473-1f3ff","👲🏻":"1f472-1f3fb","👲🏼":"1f472-1f3fc","👲🏽":"1f472-1f3fd","👲🏾":"1f472-1f3fe","👲🏿":"1f472-1f3ff","🧕🏻":"1f9d5-1f3fb","🧕🏼":"1f9d5-1f3fc","🧕🏽":"1f9d5-1f3fd","🧕🏾":"1f9d5-1f3fe","🧕🏿":"1f9d5-1f3ff","🧔🏻":"1f9d4-1f3fb","🧔🏼":"1f9d4-1f3fc","🧔🏽":"1f9d4-1f3fd","🧔🏾":"1f9d4-1f3fe","🧔🏿":"1f9d4-1f3ff","👱🏻":"1f471-1f3fb","👱🏼":"1f471-1f3fc","👱🏽":"1f471-1f3fd","👱🏾":"1f471-1f3fe","👱🏿":"1f471-1f3ff","🤵🏻":"1f935-1f3fb","🤵🏼":"1f935-1f3fc","🤵🏽":"1f935-1f3fd","🤵🏾":"1f935-1f3fe","🤵🏿":"1f935-1f3ff","👰🏻":"1f470-1f3fb","👰🏼":"1f470-1f3fc","👰🏽":"1f470-1f3fd","👰🏾":"1f470-1f3fe","👰🏿":"1f470-1f3ff","🤰🏻":"1f930-1f3fb","🤰🏼":"1f930-1f3fc","🤰🏽":"1f930-1f3fd","🤰🏾":"1f930-1f3fe","🤰🏿":"1f930-1f3ff","🤱🏻":"1f931-1f3fb","🤱🏼":"1f931-1f3fc","🤱🏽":"1f931-1f3fd","🤱🏾":"1f931-1f3fe","🤱🏿":"1f931-1f3ff","👼🏻":"1f47c-1f3fb","👼🏼":"1f47c-1f3fc","👼🏽":"1f47c-1f3fd","👼🏾":"1f47c-1f3fe","👼🏿":"1f47c-1f3ff","🎅🏻":"1f385-1f3fb","🎅🏼":"1f385-1f3fc","🎅🏽":"1f385-1f3fd","🎅🏾":"1f385-1f3fe","🎅🏿":"1f385-1f3ff","🤶🏻":"1f936-1f3fb","🤶🏼":"1f936-1f3fc","🤶🏽":"1f936-1f3fd","🤶🏾":"1f936-1f3fe","🤶🏿":"1f936-1f3ff","🦸🏻":"1f9b8-1f3fb","🦸🏼":"1f9b8-1f3fc","🦸🏽":"1f9b8-1f3fd","🦸🏾":"1f9b8-1f3fe","🦸🏿":"1f9b8-1f3ff","🦹🏻":"1f9b9-1f3fb","🦹🏼":"1f9b9-1f3fc","🦹🏽":"1f9b9-1f3fd","🦹🏾":"1f9b9-1f3fe","🦹🏿":"1f9b9-1f3ff","🧙🏻":"1f9d9-1f3fb","🧙🏼":"1f9d9-1f3fc","🧙🏽":"1f9d9-1f3fd","🧙🏾":"1f9d9-1f3fe","🧙🏿":"1f9d9-1f3ff","🧚🏻":"1f9da-1f3fb","🧚🏼":"1f9da-1f3fc","🧚🏽":"1f9da-1f3fd","🧚🏾":"1f9da-1f3fe","🧚🏿":"1f9da-1f3ff","🧛🏻":"1f9db-1f3fb","🧛🏼":"1f9db-1f3fc","🧛🏽":"1f9db-1f3fd","🧛🏾":"1f9db-1f3fe","🧛🏿":"1f9db-1f3ff","🧜🏻":"1f9dc-1f3fb","🧜🏼":"1f9dc-1f3fc","🧜🏽":"1f9dc-1f3fd","🧜🏾":"1f9dc-1f3fe","🧜🏿":"1f9dc-1f3ff","🧝🏻":"1f9dd-1f3fb","🧝🏼":"1f9dd-1f3fc","🧝🏽":"1f9dd-1f3fd","🧝🏾":"1f9dd-1f3fe","🧝🏿":"1f9dd-1f3ff","🙍🏻":"1f64d-1f3fb","🙍🏼":"1f64d-1f3fc","🙍🏽":"1f64d-1f3fd","🙍🏾":"1f64d-1f3fe","🙍🏿":"1f64d-1f3ff","🙎🏻":"1f64e-1f3fb","🙎🏼":"1f64e-1f3fc","🙎🏽":"1f64e-1f3fd","🙎🏾":"1f64e-1f3fe","🙎🏿":"1f64e-1f3ff","🙅🏻":"1f645-1f3fb","🙅🏼":"1f645-1f3fc","🙅🏽":"1f645-1f3fd","🙅🏾":"1f645-1f3fe","🙅🏿":"1f645-1f3ff","🙆🏻":"1f646-1f3fb","🙆🏼":"1f646-1f3fc","🙆🏽":"1f646-1f3fd","🙆🏾":"1f646-1f3fe","🙆🏿":"1f646-1f3ff","💁🏻":"1f481-1f3fb","💁🏼":"1f481-1f3fc","💁🏽":"1f481-1f3fd","💁🏾":"1f481-1f3fe","💁🏿":"1f481-1f3ff","🙋🏻":"1f64b-1f3fb","🙋🏼":"1f64b-1f3fc","🙋🏽":"1f64b-1f3fd","🙋🏾":"1f64b-1f3fe","🙋🏿":"1f64b-1f3ff","🙇🏻":"1f647-1f3fb","🙇🏼":"1f647-1f3fc","🙇🏽":"1f647-1f3fd","🙇🏾":"1f647-1f3fe","🙇🏿":"1f647-1f3ff","🤦🏻":"1f926-1f3fb","🤦🏼":"1f926-1f3fc","🤦🏽":"1f926-1f3fd","🤦🏾":"1f926-1f3fe","🤦🏿":"1f926-1f3ff","🤷🏻":"1f937-1f3fb","🤷🏼":"1f937-1f3fc","🤷🏽":"1f937-1f3fd","🤷🏾":"1f937-1f3fe","🤷🏿":"1f937-1f3ff","💆🏻":"1f486-1f3fb","💆🏼":"1f486-1f3fc","💆🏽":"1f486-1f3fd","💆🏾":"1f486-1f3fe","💆🏿":"1f486-1f3ff","💇🏻":"1f487-1f3fb","💇🏼":"1f487-1f3fc","💇🏽":"1f487-1f3fd","💇🏾":"1f487-1f3fe","💇🏿":"1f487-1f3ff","🚶🏻":"1f6b6-1f3fb","🚶🏼":"1f6b6-1f3fc","🚶🏽":"1f6b6-1f3fd","🚶🏾":"1f6b6-1f3fe","🚶🏿":"1f6b6-1f3ff","🏃🏻":"1f3c3-1f3fb","🏃🏼":"1f3c3-1f3fc","🏃🏽":"1f3c3-1f3fd","🏃🏾":"1f3c3-1f3fe","🏃🏿":"1f3c3-1f3ff","💃🏻":"1f483-1f3fb","💃🏼":"1f483-1f3fc","💃🏽":"1f483-1f3fd","💃🏾":"1f483-1f3fe","💃🏿":"1f483-1f3ff","🕺🏻":"1f57a-1f3fb","🕺🏼":"1f57a-1f3fc","🕺🏽":"1f57a-1f3fd","🕺🏾":"1f57a-1f3fe","🕺🏿":"1f57a-1f3ff","🧖🏻":"1f9d6-1f3fb","🧖🏼":"1f9d6-1f3fc","🧖🏽":"1f9d6-1f3fd","🧖🏾":"1f9d6-1f3fe","🧖🏿":"1f9d6-1f3ff","🧗🏻":"1f9d7-1f3fb","🧗🏼":"1f9d7-1f3fc","🧗🏽":"1f9d7-1f3fd","🧗🏾":"1f9d7-1f3fe","🧗🏿":"1f9d7-1f3ff","🧘🏻":"1f9d8-1f3fb","🧘🏼":"1f9d8-1f3fc","🧘🏽":"1f9d8-1f3fd","🧘🏾":"1f9d8-1f3fe","🧘🏿":"1f9d8-1f3ff","🛀🏻":"1f6c0-1f3fb","🛀🏼":"1f6c0-1f3fc","🛀🏽":"1f6c0-1f3fd","🛀🏾":"1f6c0-1f3fe","🛀🏿":"1f6c0-1f3ff","🛌🏻":"1f6cc-1f3fb","🛌🏼":"1f6cc-1f3fc","🛌🏽":"1f6cc-1f3fd","🛌🏾":"1f6cc-1f3fe","🛌🏿":"1f6cc-1f3ff","🕴️":"1f574","🕴🏻":"1f574-1f3fb","🕴🏼":"1f574-1f3fc","🕴🏽":"1f574-1f3fd","🕴🏾":"1f574-1f3fe","🕴🏿":"1f574-1f3ff","🗣️":"1f5e3","🏇🏻":"1f3c7-1f3fb","🏇🏼":"1f3c7-1f3fc","🏇🏽":"1f3c7-1f3fd","🏇🏾":"1f3c7-1f3fe","🏇🏿":"1f3c7-1f3ff","⛷️":"26f7","🏂🏻":"1f3c2-1f3fb","🏂🏼":"1f3c2-1f3fc","🏂🏽":"1f3c2-1f3fd","🏂🏾":"1f3c2-1f3fe","🏂🏿":"1f3c2-1f3ff","🏌️":"1f3cc","🏌🏻":"1f3cc-1f3fb","🏌🏼":"1f3cc-1f3fc","🏌🏽":"1f3cc-1f3fd","🏌🏾":"1f3cc-1f3fe","🏌🏿":"1f3cc-1f3ff","🏄🏻":"1f3c4-1f3fb","🏄🏼":"1f3c4-1f3fc","🏄🏽":"1f3c4-1f3fd","🏄🏾":"1f3c4-1f3fe","🏄🏿":"1f3c4-1f3ff","🚣🏻":"1f6a3-1f3fb","🚣🏼":"1f6a3-1f3fc","🚣🏽":"1f6a3-1f3fd","🚣🏾":"1f6a3-1f3fe","🚣🏿":"1f6a3-1f3ff","🏊🏻":"1f3ca-1f3fb","🏊🏼":"1f3ca-1f3fc","🏊🏽":"1f3ca-1f3fd","🏊🏾":"1f3ca-1f3fe","🏊🏿":"1f3ca-1f3ff","⛹️":"26f9","⛹🏻":"26f9-1f3fb","⛹🏼":"26f9-1f3fc","⛹🏽":"26f9-1f3fd","⛹🏾":"26f9-1f3fe","⛹🏿":"26f9-1f3ff","🏋️":"1f3cb","🏋🏻":"1f3cb-1f3fb","🏋🏼":"1f3cb-1f3fc","🏋🏽":"1f3cb-1f3fd","🏋🏾":"1f3cb-1f3fe","🏋🏿":"1f3cb-1f3ff","🚴🏻":"1f6b4-1f3fb","🚴🏼":"1f6b4-1f3fc","🚴🏽":"1f6b4-1f3fd","🚴🏾":"1f6b4-1f3fe","🚴🏿":"1f6b4-1f3ff","🚵🏻":"1f6b5-1f3fb","🚵🏼":"1f6b5-1f3fc","🚵🏽":"1f6b5-1f3fd","🚵🏾":"1f6b5-1f3fe","🚵🏿":"1f6b5-1f3ff","🏎️":"1f3ce","🏍️":"1f3cd","🤸🏻":"1f938-1f3fb","🤸🏼":"1f938-1f3fc","🤸🏽":"1f938-1f3fd","🤸🏾":"1f938-1f3fe","🤸🏿":"1f938-1f3ff","🤽🏻":"1f93d-1f3fb","🤽🏼":"1f93d-1f3fc","🤽🏽":"1f93d-1f3fd","🤽🏾":"1f93d-1f3fe","🤽🏿":"1f93d-1f3ff","🤾🏻":"1f93e-1f3fb","🤾🏼":"1f93e-1f3fc","🤾🏽":"1f93e-1f3fd","🤾🏾":"1f93e-1f3fe","🤾🏿":"1f93e-1f3ff","🤹🏻":"1f939-1f3fb","🤹🏼":"1f939-1f3fc","🤹🏽":"1f939-1f3fd","🤹🏾":"1f939-1f3fe","🤹🏿":"1f939-1f3ff","🤳🏻":"1f933-1f3fb","🤳🏼":"1f933-1f3fc","🤳🏽":"1f933-1f3fd","🤳🏾":"1f933-1f3fe","🤳🏿":"1f933-1f3ff","💪🏻":"1f4aa-1f3fb","💪🏼":"1f4aa-1f3fc","💪🏽":"1f4aa-1f3fd","💪🏾":"1f4aa-1f3fe","💪🏿":"1f4aa-1f3ff","🦵🏻":"1f9b5-1f3fb","🦵🏼":"1f9b5-1f3fc","🦵🏽":"1f9b5-1f3fd","🦵🏾":"1f9b5-1f3fe","🦵🏿":"1f9b5-1f3ff","🦶🏻":"1f9b6-1f3fb","🦶🏼":"1f9b6-1f3fc","🦶🏽":"1f9b6-1f3fd","🦶🏾":"1f9b6-1f3fe","🦶🏿":"1f9b6-1f3ff","👈🏻":"1f448-1f3fb","👈🏼":"1f448-1f3fc","👈🏽":"1f448-1f3fd","👈🏾":"1f448-1f3fe","👈🏿":"1f448-1f3ff","👉🏻":"1f449-1f3fb","👉🏼":"1f449-1f3fc","👉🏽":"1f449-1f3fd","👉🏾":"1f449-1f3fe","👉🏿":"1f449-1f3ff","☝️":"261d","☝🏻":"261d-1f3fb","☝🏼":"261d-1f3fc","☝🏽":"261d-1f3fd","☝🏾":"261d-1f3fe","☝🏿":"261d-1f3ff","👆🏻":"1f446-1f3fb","👆🏼":"1f446-1f3fc","👆🏽":"1f446-1f3fd","👆🏾":"1f446-1f3fe","👆🏿":"1f446-1f3ff","🖕🏻":"1f595-1f3fb","🖕🏼":"1f595-1f3fc","🖕🏽":"1f595-1f3fd","🖕🏾":"1f595-1f3fe","🖕🏿":"1f595-1f3ff","👇🏻":"1f447-1f3fb","👇🏼":"1f447-1f3fc","👇🏽":"1f447-1f3fd","👇🏾":"1f447-1f3fe","👇🏿":"1f447-1f3ff","✌️":"270c","✌🏻":"270c-1f3fb","✌🏼":"270c-1f3fc","✌🏽":"270c-1f3fd","✌🏾":"270c-1f3fe","✌🏿":"270c-1f3ff","🤞🏻":"1f91e-1f3fb","🤞🏼":"1f91e-1f3fc","🤞🏽":"1f91e-1f3fd","🤞🏾":"1f91e-1f3fe","🤞🏿":"1f91e-1f3ff","🖖🏻":"1f596-1f3fb","🖖🏼":"1f596-1f3fc","🖖🏽":"1f596-1f3fd","🖖🏾":"1f596-1f3fe","🖖🏿":"1f596-1f3ff","🤘🏻":"1f918-1f3fb","🤘🏼":"1f918-1f3fc","🤘🏽":"1f918-1f3fd","🤘🏾":"1f918-1f3fe","🤘🏿":"1f918-1f3ff","🤙🏻":"1f919-1f3fb","🤙🏼":"1f919-1f3fc","🤙🏽":"1f919-1f3fd","🤙🏾":"1f919-1f3fe","🤙🏿":"1f919-1f3ff","🖐️":"1f590","🖐🏻":"1f590-1f3fb","🖐🏼":"1f590-1f3fc","🖐🏽":"1f590-1f3fd","🖐🏾":"1f590-1f3fe","🖐🏿":"1f590-1f3ff","✋🏻":"270b-1f3fb","✋🏼":"270b-1f3fc","✋🏽":"270b-1f3fd","✋🏾":"270b-1f3fe","✋🏿":"270b-1f3ff","👌🏻":"1f44c-1f3fb","👌🏼":"1f44c-1f3fc","👌🏽":"1f44c-1f3fd","👌🏾":"1f44c-1f3fe","👌🏿":"1f44c-1f3ff","👍🏻":"1f44d-1f3fb","👍🏼":"1f44d-1f3fc","👍🏽":"1f44d-1f3fd","👍🏾":"1f44d-1f3fe","👍🏿":"1f44d-1f3ff","👎🏻":"1f44e-1f3fb","👎🏼":"1f44e-1f3fc","👎🏽":"1f44e-1f3fd","👎🏾":"1f44e-1f3fe","👎🏿":"1f44e-1f3ff","✊🏻":"270a-1f3fb","✊🏼":"270a-1f3fc","✊🏽":"270a-1f3fd","✊🏾":"270a-1f3fe","✊🏿":"270a-1f3ff","👊🏻":"1f44a-1f3fb","👊🏼":"1f44a-1f3fc","👊🏽":"1f44a-1f3fd","👊🏾":"1f44a-1f3fe","👊🏿":"1f44a-1f3ff","🤛🏻":"1f91b-1f3fb","🤛🏼":"1f91b-1f3fc","🤛🏽":"1f91b-1f3fd","🤛🏾":"1f91b-1f3fe","🤛🏿":"1f91b-1f3ff","🤜🏻":"1f91c-1f3fb","🤜🏼":"1f91c-1f3fc","🤜🏽":"1f91c-1f3fd","🤜🏾":"1f91c-1f3fe","🤜🏿":"1f91c-1f3ff","🤚🏻":"1f91a-1f3fb","🤚🏼":"1f91a-1f3fc","🤚🏽":"1f91a-1f3fd","🤚🏾":"1f91a-1f3fe","🤚🏿":"1f91a-1f3ff","👋🏻":"1f44b-1f3fb","👋🏼":"1f44b-1f3fc","👋🏽":"1f44b-1f3fd","👋🏾":"1f44b-1f3fe","👋🏿":"1f44b-1f3ff","🤟🏻":"1f91f-1f3fb","🤟🏼":"1f91f-1f3fc","🤟🏽":"1f91f-1f3fd","🤟🏾":"1f91f-1f3fe","🤟🏿":"1f91f-1f3ff","✍️":"270d","✍🏻":"270d-1f3fb","✍🏼":"270d-1f3fc","✍🏽":"270d-1f3fd","✍🏾":"270d-1f3fe","✍🏿":"270d-1f3ff","👏🏻":"1f44f-1f3fb","👏🏼":"1f44f-1f3fc","👏🏽":"1f44f-1f3fd","👏🏾":"1f44f-1f3fe","👏🏿":"1f44f-1f3ff","👐🏻":"1f450-1f3fb","👐🏼":"1f450-1f3fc","👐🏽":"1f450-1f3fd","👐🏾":"1f450-1f3fe","👐🏿":"1f450-1f3ff","🙌🏻":"1f64c-1f3fb","🙌🏼":"1f64c-1f3fc","🙌🏽":"1f64c-1f3fd","🙌🏾":"1f64c-1f3fe","🙌🏿":"1f64c-1f3ff","🤲🏻":"1f932-1f3fb","🤲🏼":"1f932-1f3fc","🤲🏽":"1f932-1f3fd","🤲🏾":"1f932-1f3fe","🤲🏿":"1f932-1f3ff","🙏🏻":"1f64f-1f3fb","🙏🏼":"1f64f-1f3fc","🙏🏽":"1f64f-1f3fd","🙏🏾":"1f64f-1f3fe","🙏🏿":"1f64f-1f3ff","💅🏻":"1f485-1f3fb","💅🏼":"1f485-1f3fc","💅🏽":"1f485-1f3fd","💅🏾":"1f485-1f3fe","💅🏿":"1f485-1f3ff","👂🏻":"1f442-1f3fb","👂🏼":"1f442-1f3fc","👂🏽":"1f442-1f3fd","👂🏾":"1f442-1f3fe","👂🏿":"1f442-1f3ff","👃🏻":"1f443-1f3fb","👃🏼":"1f443-1f3fc","👃🏽":"1f443-1f3fd","👃🏾":"1f443-1f3fe","👃🏿":"1f443-1f3ff","👁️":"1f441","❤️":"2764","❣️":"2763","🗨️":"1f5e8","🗯️":"1f5ef","🕳️":"1f573","🕶️":"1f576","🛍️":"1f6cd","⛑️":"26d1","🐿️":"1f43f","🕊️":"1f54a","🕷️":"1f577","🕸️":"1f578","🏵️":"1f3f5","☘️":"2618","🌶️":"1f336","🍽️":"1f37d","🗺️":"1f5fa","🏔️":"1f3d4","⛰️":"26f0","🏕️":"1f3d5","🏖️":"1f3d6","🏜️":"1f3dc","🏝️":"1f3dd","🏞️":"1f3de","🏟️":"1f3df","🏛️":"1f3db","🏗️":"1f3d7","🏘️":"1f3d8","🏚️":"1f3da","⛩️":"26e9","🏙️":"1f3d9","♨️":"2668","🛣️":"1f6e3","🛤️":"1f6e4","🛢️":"1f6e2","🛳️":"1f6f3","⛴️":"26f4","🛥️":"1f6e5","✈️":"2708","🛩️":"1f6e9","🛰️":"1f6f0","🛎️":"1f6ce","⏱️":"23f1","⏲️":"23f2","🕰️":"1f570","🌡️":"1f321","☀️":"2600","☁️":"2601","⛈️":"26c8","🌤️":"1f324","🌥️":"1f325","🌦️":"1f326","🌧️":"1f327","🌨️":"1f328","🌩️":"1f329","🌪️":"1f32a","🌫️":"1f32b","🌬️":"1f32c","☂️":"2602","⛱️":"26f1","❄️":"2744","☃️":"2603","☄️":"2604","🎗️":"1f397","🎟️":"1f39f","🎖️":"1f396","⛸️":"26f8","🕹️":"1f579","♠️":"2660","♥️":"2665","♦️":"2666","♣️":"2663","♟️":"265f","🖼️":"1f5bc","🎙️":"1f399","🎚️":"1f39a","🎛️":"1f39b","☎️":"260e","🖥️":"1f5a5","🖨️":"1f5a8","⌨️":"2328","🖱️":"1f5b1","🖲️":"1f5b2","🎞️":"1f39e","📽️":"1f4fd","🕯️":"1f56f","🗞️":"1f5de","🏷️":"1f3f7","✉️":"2709","🗳️":"1f5f3","✏️":"270f","✒️":"2712","🖋️":"1f58b","🖊️":"1f58a","🖌️":"1f58c","🖍️":"1f58d","🗂️":"1f5c2","🗒️":"1f5d2","🗓️":"1f5d3","🖇️":"1f587","✂️":"2702","🗃️":"1f5c3","🗄️":"1f5c4","🗑️":"1f5d1","🗝️":"1f5dd","⛏️":"26cf","⚒️":"2692","🛠️":"1f6e0","🗡️":"1f5e1","⚔️":"2694","🛡️":"1f6e1","⚙️":"2699","🗜️":"1f5dc","⚖️":"2696","⛓️":"26d3","⚗️":"2697","🛏️":"1f6cf","🛋️":"1f6cb","⚰️":"26b0","⚱️":"26b1","⚠️":"26a0","☢️":"2622","☣️":"2623","⬆️":"2b06","↗️":"2197","➡️":"27a1","↘️":"2198","⬇️":"2b07","↙️":"2199","⬅️":"2b05","↖️":"2196","↕️":"2195","↔️":"2194","↩️":"21a9","↪️":"21aa","⤴️":"2934","⤵️":"2935","⚛️":"269b","🕉️":"1f549","✡️":"2721","☸️":"2638","☯️":"262f","✝️":"271d","☦️":"2626","☪️":"262a","☮️":"262e","▶️":"25b6","⏭️":"23ed","⏯️":"23ef","◀️":"25c0","⏮️":"23ee","⏸️":"23f8","⏹️":"23f9","⏺️":"23fa","⏏️":"23cf","♀️":"2640","♂️":"2642","⚕️":"2695","♾️":"267e","♻️":"267b","⚜️":"269c","☑️":"2611","✔️":"2714","✖️":"2716","〽️":"303d","✳️":"2733","✴️":"2734","❇️":"2747","‼️":"203c","⁉️":"2049","〰️":"3030","©️":"a9","®️":"ae","™️":"2122","#⃣":"23-20e3","*⃣":"2a-20e3","0⃣":"30-20e3","1⃣":"31-20e3","2⃣":"32-20e3","3⃣":"33-20e3","4⃣":"34-20e3","5⃣":"35-20e3","6⃣":"36-20e3","7⃣":"37-20e3","8⃣":"38-20e3","9⃣":"39-20e3","🅰️":"1f170","🅱️":"1f171","ℹ️":"2139","Ⓜ️":"24c2","🅾️":"1f17e","🅿️":"1f17f","🈂️":"1f202","🈷️":"1f237","㊗️":"3297","㊙️":"3299","▪️":"25aa","▫️":"25ab","◻️":"25fb","◼️":"25fc","🏳️":"1f3f3","🇦🇨":"1f1e6-1f1e8","🇦🇩":"1f1e6-1f1e9","🇦🇪":"1f1e6-1f1ea","🇦🇫":"1f1e6-1f1eb","🇦🇬":"1f1e6-1f1ec","🇦🇮":"1f1e6-1f1ee","🇦🇱":"1f1e6-1f1f1","🇦🇲":"1f1e6-1f1f2","🇦🇴":"1f1e6-1f1f4","🇦🇶":"1f1e6-1f1f6","🇦🇷":"1f1e6-1f1f7","🇦🇸":"1f1e6-1f1f8","🇦🇹":"1f1e6-1f1f9","🇦🇺":"1f1e6-1f1fa","🇦🇼":"1f1e6-1f1fc","🇦🇽":"1f1e6-1f1fd","🇦🇿":"1f1e6-1f1ff","🇧🇦":"1f1e7-1f1e6","🇧🇧":"1f1e7-1f1e7","🇧🇩":"1f1e7-1f1e9","🇧🇪":"1f1e7-1f1ea","🇧🇫":"1f1e7-1f1eb","🇧🇬":"1f1e7-1f1ec","🇧🇭":"1f1e7-1f1ed","🇧🇮":"1f1e7-1f1ee","🇧🇯":"1f1e7-1f1ef","🇧🇱":"1f1e7-1f1f1","🇧🇲":"1f1e7-1f1f2","🇧🇳":"1f1e7-1f1f3","🇧🇴":"1f1e7-1f1f4","🇧🇶":"1f1e7-1f1f6","🇧🇷":"1f1e7-1f1f7","🇧🇸":"1f1e7-1f1f8","🇧🇹":"1f1e7-1f1f9","🇧🇻":"1f1e7-1f1fb","🇧🇼":"1f1e7-1f1fc","🇧🇾":"1f1e7-1f1fe","🇧🇿":"1f1e7-1f1ff","🇨🇦":"1f1e8-1f1e6","🇨🇨":"1f1e8-1f1e8","🇨🇩":"1f1e8-1f1e9","🇨🇫":"1f1e8-1f1eb","🇨🇬":"1f1e8-1f1ec","🇨🇭":"1f1e8-1f1ed","🇨🇮":"1f1e8-1f1ee","🇨🇰":"1f1e8-1f1f0","🇨🇱":"1f1e8-1f1f1","🇨🇲":"1f1e8-1f1f2","🇨🇳":"1f1e8-1f1f3","🇨🇴":"1f1e8-1f1f4","🇨🇵":"1f1e8-1f1f5","🇨🇷":"1f1e8-1f1f7","🇨🇺":"1f1e8-1f1fa","🇨🇻":"1f1e8-1f1fb","🇨🇼":"1f1e8-1f1fc","🇨🇽":"1f1e8-1f1fd","🇨🇾":"1f1e8-1f1fe","🇨🇿":"1f1e8-1f1ff","🇩🇪":"1f1e9-1f1ea","🇩🇬":"1f1e9-1f1ec","🇩🇯":"1f1e9-1f1ef","🇩🇰":"1f1e9-1f1f0","🇩🇲":"1f1e9-1f1f2","🇩🇴":"1f1e9-1f1f4","🇩🇿":"1f1e9-1f1ff","🇪🇦":"1f1ea-1f1e6","🇪🇨":"1f1ea-1f1e8","🇪🇪":"1f1ea-1f1ea","🇪🇬":"1f1ea-1f1ec","🇪🇭":"1f1ea-1f1ed","🇪🇷":"1f1ea-1f1f7","🇪🇸":"1f1ea-1f1f8","🇪🇹":"1f1ea-1f1f9","🇪🇺":"1f1ea-1f1fa","🇫🇮":"1f1eb-1f1ee","🇫🇯":"1f1eb-1f1ef","🇫🇰":"1f1eb-1f1f0","🇫🇲":"1f1eb-1f1f2","🇫🇴":"1f1eb-1f1f4","🇫🇷":"1f1eb-1f1f7","🇬🇦":"1f1ec-1f1e6","🇬🇧":"1f1ec-1f1e7","🇬🇩":"1f1ec-1f1e9","🇬🇪":"1f1ec-1f1ea","🇬🇫":"1f1ec-1f1eb","🇬🇬":"1f1ec-1f1ec","🇬🇭":"1f1ec-1f1ed","🇬🇮":"1f1ec-1f1ee","🇬🇱":"1f1ec-1f1f1","🇬🇲":"1f1ec-1f1f2","🇬🇳":"1f1ec-1f1f3","🇬🇵":"1f1ec-1f1f5","🇬🇶":"1f1ec-1f1f6","🇬🇷":"1f1ec-1f1f7","🇬🇸":"1f1ec-1f1f8","🇬🇹":"1f1ec-1f1f9","🇬🇺":"1f1ec-1f1fa","🇬🇼":"1f1ec-1f1fc","🇬🇾":"1f1ec-1f1fe","🇭🇰":"1f1ed-1f1f0","🇭🇲":"1f1ed-1f1f2","🇭🇳":"1f1ed-1f1f3","🇭🇷":"1f1ed-1f1f7","🇭🇹":"1f1ed-1f1f9","🇭🇺":"1f1ed-1f1fa","🇮🇨":"1f1ee-1f1e8","🇮🇩":"1f1ee-1f1e9","🇮🇪":"1f1ee-1f1ea","🇮🇱":"1f1ee-1f1f1","🇮🇲":"1f1ee-1f1f2","🇮🇳":"1f1ee-1f1f3","🇮🇴":"1f1ee-1f1f4","🇮🇶":"1f1ee-1f1f6","🇮🇷":"1f1ee-1f1f7","🇮🇸":"1f1ee-1f1f8","🇮🇹":"1f1ee-1f1f9","🇯🇪":"1f1ef-1f1ea","🇯🇲":"1f1ef-1f1f2","🇯🇴":"1f1ef-1f1f4","🇯🇵":"1f1ef-1f1f5","🇰🇪":"1f1f0-1f1ea","🇰🇬":"1f1f0-1f1ec","🇰🇭":"1f1f0-1f1ed","🇰🇮":"1f1f0-1f1ee","🇰🇲":"1f1f0-1f1f2","🇰🇳":"1f1f0-1f1f3","🇰🇵":"1f1f0-1f1f5","🇰🇷":"1f1f0-1f1f7","🇰🇼":"1f1f0-1f1fc","🇰🇾":"1f1f0-1f1fe","🇰🇿":"1f1f0-1f1ff","🇱🇦":"1f1f1-1f1e6","🇱🇧":"1f1f1-1f1e7","🇱🇨":"1f1f1-1f1e8","🇱🇮":"1f1f1-1f1ee","🇱🇰":"1f1f1-1f1f0","🇱🇷":"1f1f1-1f1f7","🇱🇸":"1f1f1-1f1f8","🇱🇹":"1f1f1-1f1f9","🇱🇺":"1f1f1-1f1fa","🇱🇻":"1f1f1-1f1fb","🇱🇾":"1f1f1-1f1fe","🇲🇦":"1f1f2-1f1e6","🇲🇨":"1f1f2-1f1e8","🇲🇩":"1f1f2-1f1e9","🇲🇪":"1f1f2-1f1ea","🇲🇫":"1f1f2-1f1eb","🇲🇬":"1f1f2-1f1ec","🇲🇭":"1f1f2-1f1ed","🇲🇰":"1f1f2-1f1f0","🇲🇱":"1f1f2-1f1f1","🇲🇲":"1f1f2-1f1f2","🇲🇳":"1f1f2-1f1f3","🇲🇴":"1f1f2-1f1f4","🇲🇵":"1f1f2-1f1f5","🇲🇶":"1f1f2-1f1f6","🇲🇷":"1f1f2-1f1f7","🇲🇸":"1f1f2-1f1f8","🇲🇹":"1f1f2-1f1f9","🇲🇺":"1f1f2-1f1fa","🇲🇻":"1f1f2-1f1fb","🇲🇼":"1f1f2-1f1fc","🇲🇽":"1f1f2-1f1fd","🇲🇾":"1f1f2-1f1fe","🇲🇿":"1f1f2-1f1ff","🇳🇦":"1f1f3-1f1e6","🇳🇨":"1f1f3-1f1e8","🇳🇪":"1f1f3-1f1ea","🇳🇫":"1f1f3-1f1eb","🇳🇬":"1f1f3-1f1ec","🇳🇮":"1f1f3-1f1ee","🇳🇱":"1f1f3-1f1f1","🇳🇴":"1f1f3-1f1f4","🇳🇵":"1f1f3-1f1f5","🇳🇷":"1f1f3-1f1f7","🇳🇺":"1f1f3-1f1fa","🇳🇿":"1f1f3-1f1ff","🇴🇲":"1f1f4-1f1f2","🇵🇦":"1f1f5-1f1e6","🇵🇪":"1f1f5-1f1ea","🇵🇫":"1f1f5-1f1eb","🇵🇬":"1f1f5-1f1ec","🇵🇭":"1f1f5-1f1ed","🇵🇰":"1f1f5-1f1f0","🇵🇱":"1f1f5-1f1f1","🇵🇲":"1f1f5-1f1f2","🇵🇳":"1f1f5-1f1f3","🇵🇷":"1f1f5-1f1f7","🇵🇸":"1f1f5-1f1f8","🇵🇹":"1f1f5-1f1f9","🇵🇼":"1f1f5-1f1fc","🇵🇾":"1f1f5-1f1fe","🇶🇦":"1f1f6-1f1e6","🇷🇪":"1f1f7-1f1ea","🇷🇴":"1f1f7-1f1f4","🇷🇸":"1f1f7-1f1f8","🇷🇺":"1f1f7-1f1fa","🇷🇼":"1f1f7-1f1fc","🇸🇦":"1f1f8-1f1e6","🇸🇧":"1f1f8-1f1e7","🇸🇨":"1f1f8-1f1e8","🇸🇩":"1f1f8-1f1e9","🇸🇪":"1f1f8-1f1ea","🇸🇬":"1f1f8-1f1ec","🇸🇭":"1f1f8-1f1ed","🇸🇮":"1f1f8-1f1ee","🇸🇯":"1f1f8-1f1ef","🇸🇰":"1f1f8-1f1f0","🇸🇱":"1f1f8-1f1f1","🇸🇲":"1f1f8-1f1f2","🇸🇳":"1f1f8-1f1f3","🇸🇴":"1f1f8-1f1f4","🇸🇷":"1f1f8-1f1f7","🇸🇸":"1f1f8-1f1f8","🇸🇹":"1f1f8-1f1f9","🇸🇻":"1f1f8-1f1fb","🇸🇽":"1f1f8-1f1fd","🇸🇾":"1f1f8-1f1fe","🇸🇿":"1f1f8-1f1ff","🇹🇦":"1f1f9-1f1e6","🇹🇨":"1f1f9-1f1e8","🇹🇩":"1f1f9-1f1e9","🇹🇫":"1f1f9-1f1eb","🇹🇬":"1f1f9-1f1ec","🇹🇭":"1f1f9-1f1ed","🇹🇯":"1f1f9-1f1ef","🇹🇰":"1f1f9-1f1f0","🇹🇱":"1f1f9-1f1f1","🇹🇲":"1f1f9-1f1f2","🇹🇳":"1f1f9-1f1f3","🇹🇴":"1f1f9-1f1f4","🇹🇷":"1f1f9-1f1f7","🇹🇹":"1f1f9-1f1f9","🇹🇻":"1f1f9-1f1fb","🇹🇼":"1f1f9-1f1fc","🇹🇿":"1f1f9-1f1ff","🇺🇦":"1f1fa-1f1e6","🇺🇬":"1f1fa-1f1ec","🇺🇲":"1f1fa-1f1f2","🇺🇳":"1f1fa-1f1f3","🇺🇸":"1f1fa-1f1f8","🇺🇾":"1f1fa-1f1fe","🇺🇿":"1f1fa-1f1ff","🇻🇦":"1f1fb-1f1e6","🇻🇨":"1f1fb-1f1e8","🇻🇪":"1f1fb-1f1ea","🇻🇬":"1f1fb-1f1ec","🇻🇮":"1f1fb-1f1ee","🇻🇳":"1f1fb-1f1f3","🇻🇺":"1f1fb-1f1fa","🇼🇫":"1f1fc-1f1eb","🇼🇸":"1f1fc-1f1f8","🇽🇰":"1f1fd-1f1f0","🇾🇪":"1f1fe-1f1ea","🇾🇹":"1f1fe-1f1f9","🇿🇦":"1f1ff-1f1e6","🇿🇲":"1f1ff-1f1f2","🇿🇼":"1f1ff-1f1fc","👨‍⚕":"1f468-200d-2695-fe0f","👩‍⚕":"1f469-200d-2695-fe0f","👨‍🎓":"1f468-200d-1f393","👩‍🎓":"1f469-200d-1f393","👨‍🏫":"1f468-200d-1f3eb","👩‍🏫":"1f469-200d-1f3eb","👨‍⚖":"1f468-200d-2696-fe0f","👩‍⚖":"1f469-200d-2696-fe0f","👨‍🌾":"1f468-200d-1f33e","👩‍🌾":"1f469-200d-1f33e","👨‍🍳":"1f468-200d-1f373","👩‍🍳":"1f469-200d-1f373","👨‍🔧":"1f468-200d-1f527","👩‍🔧":"1f469-200d-1f527","👨‍🏭":"1f468-200d-1f3ed","👩‍🏭":"1f469-200d-1f3ed","👨‍💼":"1f468-200d-1f4bc","👩‍💼":"1f469-200d-1f4bc","👨‍🔬":"1f468-200d-1f52c","👩‍🔬":"1f469-200d-1f52c","👨‍💻":"1f468-200d-1f4bb","👩‍💻":"1f469-200d-1f4bb","👨‍🎤":"1f468-200d-1f3a4","👩‍🎤":"1f469-200d-1f3a4","👨‍🎨":"1f468-200d-1f3a8","👩‍🎨":"1f469-200d-1f3a8","👨‍✈":"1f468-200d-2708-fe0f","👩‍✈":"1f469-200d-2708-fe0f","👨‍🚀":"1f468-200d-1f680","👩‍🚀":"1f469-200d-1f680","👨‍🚒":"1f468-200d-1f692","👩‍🚒":"1f469-200d-1f692","👮‍♂":"1f46e-200d-2642-fe0f","👮‍♀":"1f46e-200d-2640-fe0f","🕵‍♂":"1f575-fe0f-200d-2642-fe0f","🕵‍♀":"1f575-fe0f-200d-2640-fe0f","💂‍♂":"1f482-200d-2642-fe0f","💂‍♀":"1f482-200d-2640-fe0f","👷‍♂":"1f477-200d-2642-fe0f","👷‍♀":"1f477-200d-2640-fe0f","👳‍♂":"1f473-200d-2642-fe0f","👳‍♀":"1f473-200d-2640-fe0f","👱‍♂":"1f471-200d-2642-fe0f","👱‍♀":"1f471-200d-2640-fe0f","👨‍🦰":"1f468-200d-1f9b0","👩‍🦰":"1f469-200d-1f9b0","👨‍🦱":"1f468-200d-1f9b1","👩‍🦱":"1f469-200d-1f9b1","👨‍🦲":"1f468-200d-1f9b2","👩‍🦲":"1f469-200d-1f9b2","👨‍🦳":"1f468-200d-1f9b3","👩‍🦳":"1f469-200d-1f9b3","🦸‍♀":"1f9b8-200d-2640-fe0f","🦸‍♂":"1f9b8-200d-2642-fe0f","🦹‍♀":"1f9b9-200d-2640-fe0f","🦹‍♂":"1f9b9-200d-2642-fe0f","🧙‍♀":"1f9d9-200d-2640-fe0f","🧙‍♂":"1f9d9-200d-2642-fe0f","🧚‍♀":"1f9da-200d-2640-fe0f","🧚‍♂":"1f9da-200d-2642-fe0f","🧛‍♀":"1f9db-200d-2640-fe0f","🧛‍♂":"1f9db-200d-2642-fe0f","🧜‍♀":"1f9dc-200d-2640-fe0f","🧜‍♂":"1f9dc-200d-2642-fe0f","🧝‍♀":"1f9dd-200d-2640-fe0f","🧝‍♂":"1f9dd-200d-2642-fe0f","🧞‍♀":"1f9de-200d-2640-fe0f","🧞‍♂":"1f9de-200d-2642-fe0f","🧟‍♀":"1f9df-200d-2640-fe0f","🧟‍♂":"1f9df-200d-2642-fe0f","🙍‍♂":"1f64d-200d-2642-fe0f","🙍‍♀":"1f64d-200d-2640-fe0f","🙎‍♂":"1f64e-200d-2642-fe0f","🙎‍♀":"1f64e-200d-2640-fe0f","🙅‍♂":"1f645-200d-2642-fe0f","🙅‍♀":"1f645-200d-2640-fe0f","🙆‍♂":"1f646-200d-2642-fe0f","🙆‍♀":"1f646-200d-2640-fe0f","💁‍♂":"1f481-200d-2642-fe0f","💁‍♀":"1f481-200d-2640-fe0f","🙋‍♂":"1f64b-200d-2642-fe0f","🙋‍♀":"1f64b-200d-2640-fe0f","🙇‍♂":"1f647-200d-2642-fe0f","🙇‍♀":"1f647-200d-2640-fe0f","🤦‍♂":"1f926-200d-2642-fe0f","🤦‍♀":"1f926-200d-2640-fe0f","🤷‍♂":"1f937-200d-2642-fe0f","🤷‍♀":"1f937-200d-2640-fe0f","💆‍♂":"1f486-200d-2642-fe0f","💆‍♀":"1f486-200d-2640-fe0f","💇‍♂":"1f487-200d-2642-fe0f","💇‍♀":"1f487-200d-2640-fe0f","🚶‍♂":"1f6b6-200d-2642-fe0f","🚶‍♀":"1f6b6-200d-2640-fe0f","🏃‍♂":"1f3c3-200d-2642-fe0f","🏃‍♀":"1f3c3-200d-2640-fe0f","👯‍♂":"1f46f-200d-2642-fe0f","👯‍♀":"1f46f-200d-2640-fe0f","🧖‍♀":"1f9d6-200d-2640-fe0f","🧖‍♂":"1f9d6-200d-2642-fe0f","🧗‍♀":"1f9d7-200d-2640-fe0f","🧗‍♂":"1f9d7-200d-2642-fe0f","🧘‍♀":"1f9d8-200d-2640-fe0f","🧘‍♂":"1f9d8-200d-2642-fe0f","🏌‍♂":"1f3cc-fe0f-200d-2642-fe0f","🏌‍♀":"1f3cc-fe0f-200d-2640-fe0f","🏄‍♂":"1f3c4-200d-2642-fe0f","🏄‍♀":"1f3c4-200d-2640-fe0f","🚣‍♂":"1f6a3-200d-2642-fe0f","🚣‍♀":"1f6a3-200d-2640-fe0f","🏊‍♂":"1f3ca-200d-2642-fe0f","🏊‍♀":"1f3ca-200d-2640-fe0f","⛹‍♂":"26f9-fe0f-200d-2642-fe0f","⛹‍♀":"26f9-fe0f-200d-2640-fe0f","🏋‍♂":"1f3cb-fe0f-200d-2642-fe0f","🏋‍♀":"1f3cb-fe0f-200d-2640-fe0f","🚴‍♂":"1f6b4-200d-2642-fe0f","🚴‍♀":"1f6b4-200d-2640-fe0f","🚵‍♂":"1f6b5-200d-2642-fe0f","🚵‍♀":"1f6b5-200d-2640-fe0f","🤸‍♂":"1f938-200d-2642-fe0f","🤸‍♀":"1f938-200d-2640-fe0f","🤼‍♂":"1f93c-200d-2642-fe0f","🤼‍♀":"1f93c-200d-2640-fe0f","🤽‍♂":"1f93d-200d-2642-fe0f","🤽‍♀":"1f93d-200d-2640-fe0f","🤾‍♂":"1f93e-200d-2642-fe0f","🤾‍♀":"1f93e-200d-2640-fe0f","🤹‍♂":"1f939-200d-2642-fe0f","🤹‍♀":"1f939-200d-2640-fe0f","👨‍👦":"1f468-200d-1f466","👨‍👧":"1f468-200d-1f467","👩‍👦":"1f469-200d-1f466","👩‍👧":"1f469-200d-1f467","👁‍🗨":"1f441-200d-1f5e8","#️⃣":"23-20e3","*️⃣":"2a-20e3","0️⃣":"30-20e3","1️⃣":"31-20e3","2️⃣":"32-20e3","3️⃣":"33-20e3","4️⃣":"34-20e3","5️⃣":"35-20e3","6️⃣":"36-20e3","7️⃣":"37-20e3","8️⃣":"38-20e3","9️⃣":"39-20e3","🏳‍🌈":"1f3f3-fe0f-200d-1f308","🏴‍☠":"1f3f4-200d-2620-fe0f","👨‍⚕️":"1f468-200d-2695-fe0f","👨🏻‍⚕":"1f468-1f3fb-200d-2695-fe0f","👨🏼‍⚕":"1f468-1f3fc-200d-2695-fe0f","👨🏽‍⚕":"1f468-1f3fd-200d-2695-fe0f","👨🏾‍⚕":"1f468-1f3fe-200d-2695-fe0f","👨🏿‍⚕":"1f468-1f3ff-200d-2695-fe0f","👩‍⚕️":"1f469-200d-2695-fe0f","👩🏻‍⚕":"1f469-1f3fb-200d-2695-fe0f","👩🏼‍⚕":"1f469-1f3fc-200d-2695-fe0f","👩🏽‍⚕":"1f469-1f3fd-200d-2695-fe0f","👩🏾‍⚕":"1f469-1f3fe-200d-2695-fe0f","👩🏿‍⚕":"1f469-1f3ff-200d-2695-fe0f","👨🏻‍🎓":"1f468-1f3fb-200d-1f393","👨🏼‍🎓":"1f468-1f3fc-200d-1f393","👨🏽‍🎓":"1f468-1f3fd-200d-1f393","👨🏾‍🎓":"1f468-1f3fe-200d-1f393","👨🏿‍🎓":"1f468-1f3ff-200d-1f393","👩🏻‍🎓":"1f469-1f3fb-200d-1f393","👩🏼‍🎓":"1f469-1f3fc-200d-1f393","👩🏽‍🎓":"1f469-1f3fd-200d-1f393","👩🏾‍🎓":"1f469-1f3fe-200d-1f393","👩🏿‍🎓":"1f469-1f3ff-200d-1f393","👨🏻‍🏫":"1f468-1f3fb-200d-1f3eb","👨🏼‍🏫":"1f468-1f3fc-200d-1f3eb","👨🏽‍🏫":"1f468-1f3fd-200d-1f3eb","👨🏾‍🏫":"1f468-1f3fe-200d-1f3eb","👨🏿‍🏫":"1f468-1f3ff-200d-1f3eb","👩🏻‍🏫":"1f469-1f3fb-200d-1f3eb","👩🏼‍🏫":"1f469-1f3fc-200d-1f3eb","👩🏽‍🏫":"1f469-1f3fd-200d-1f3eb","👩🏾‍🏫":"1f469-1f3fe-200d-1f3eb","👩🏿‍🏫":"1f469-1f3ff-200d-1f3eb","👨‍⚖️":"1f468-200d-2696-fe0f","👨🏻‍⚖":"1f468-1f3fb-200d-2696-fe0f","👨🏼‍⚖":"1f468-1f3fc-200d-2696-fe0f","👨🏽‍⚖":"1f468-1f3fd-200d-2696-fe0f","👨🏾‍⚖":"1f468-1f3fe-200d-2696-fe0f","👨🏿‍⚖":"1f468-1f3ff-200d-2696-fe0f","👩‍⚖️":"1f469-200d-2696-fe0f","👩🏻‍⚖":"1f469-1f3fb-200d-2696-fe0f","👩🏼‍⚖":"1f469-1f3fc-200d-2696-fe0f","👩🏽‍⚖":"1f469-1f3fd-200d-2696-fe0f","👩🏾‍⚖":"1f469-1f3fe-200d-2696-fe0f","👩🏿‍⚖":"1f469-1f3ff-200d-2696-fe0f","👨🏻‍🌾":"1f468-1f3fb-200d-1f33e","👨🏼‍🌾":"1f468-1f3fc-200d-1f33e","👨🏽‍🌾":"1f468-1f3fd-200d-1f33e","👨🏾‍🌾":"1f468-1f3fe-200d-1f33e","👨🏿‍🌾":"1f468-1f3ff-200d-1f33e","👩🏻‍🌾":"1f469-1f3fb-200d-1f33e","👩🏼‍🌾":"1f469-1f3fc-200d-1f33e","👩🏽‍🌾":"1f469-1f3fd-200d-1f33e","👩🏾‍🌾":"1f469-1f3fe-200d-1f33e","👩🏿‍🌾":"1f469-1f3ff-200d-1f33e","👨🏻‍🍳":"1f468-1f3fb-200d-1f373","👨🏼‍🍳":"1f468-1f3fc-200d-1f373","👨🏽‍🍳":"1f468-1f3fd-200d-1f373","👨🏾‍🍳":"1f468-1f3fe-200d-1f373","👨🏿‍🍳":"1f468-1f3ff-200d-1f373","👩🏻‍🍳":"1f469-1f3fb-200d-1f373","👩🏼‍🍳":"1f469-1f3fc-200d-1f373","👩🏽‍🍳":"1f469-1f3fd-200d-1f373","👩🏾‍🍳":"1f469-1f3fe-200d-1f373","👩🏿‍🍳":"1f469-1f3ff-200d-1f373","👨🏻‍🔧":"1f468-1f3fb-200d-1f527","👨🏼‍🔧":"1f468-1f3fc-200d-1f527","👨🏽‍🔧":"1f468-1f3fd-200d-1f527","👨🏾‍🔧":"1f468-1f3fe-200d-1f527","👨🏿‍🔧":"1f468-1f3ff-200d-1f527","👩🏻‍🔧":"1f469-1f3fb-200d-1f527","👩🏼‍🔧":"1f469-1f3fc-200d-1f527","👩🏽‍🔧":"1f469-1f3fd-200d-1f527","👩🏾‍🔧":"1f469-1f3fe-200d-1f527","👩🏿‍🔧":"1f469-1f3ff-200d-1f527","👨🏻‍🏭":"1f468-1f3fb-200d-1f3ed","👨🏼‍🏭":"1f468-1f3fc-200d-1f3ed","👨🏽‍🏭":"1f468-1f3fd-200d-1f3ed","👨🏾‍🏭":"1f468-1f3fe-200d-1f3ed","👨🏿‍🏭":"1f468-1f3ff-200d-1f3ed","👩🏻‍🏭":"1f469-1f3fb-200d-1f3ed","👩🏼‍🏭":"1f469-1f3fc-200d-1f3ed","👩🏽‍🏭":"1f469-1f3fd-200d-1f3ed","👩🏾‍🏭":"1f469-1f3fe-200d-1f3ed","👩🏿‍🏭":"1f469-1f3ff-200d-1f3ed","👨🏻‍💼":"1f468-1f3fb-200d-1f4bc","👨🏼‍💼":"1f468-1f3fc-200d-1f4bc","👨🏽‍💼":"1f468-1f3fd-200d-1f4bc","👨🏾‍💼":"1f468-1f3fe-200d-1f4bc","👨🏿‍💼":"1f468-1f3ff-200d-1f4bc","👩🏻‍💼":"1f469-1f3fb-200d-1f4bc","👩🏼‍💼":"1f469-1f3fc-200d-1f4bc","👩🏽‍💼":"1f469-1f3fd-200d-1f4bc","👩🏾‍💼":"1f469-1f3fe-200d-1f4bc","👩🏿‍💼":"1f469-1f3ff-200d-1f4bc","👨🏻‍🔬":"1f468-1f3fb-200d-1f52c","👨🏼‍🔬":"1f468-1f3fc-200d-1f52c","👨🏽‍🔬":"1f468-1f3fd-200d-1f52c","👨🏾‍🔬":"1f468-1f3fe-200d-1f52c","👨🏿‍🔬":"1f468-1f3ff-200d-1f52c","👩🏻‍🔬":"1f469-1f3fb-200d-1f52c","👩🏼‍🔬":"1f469-1f3fc-200d-1f52c","👩🏽‍🔬":"1f469-1f3fd-200d-1f52c","👩🏾‍🔬":"1f469-1f3fe-200d-1f52c","👩🏿‍🔬":"1f469-1f3ff-200d-1f52c","👨🏻‍💻":"1f468-1f3fb-200d-1f4bb","👨🏼‍💻":"1f468-1f3fc-200d-1f4bb","👨🏽‍💻":"1f468-1f3fd-200d-1f4bb","👨🏾‍💻":"1f468-1f3fe-200d-1f4bb","👨🏿‍💻":"1f468-1f3ff-200d-1f4bb","👩🏻‍💻":"1f469-1f3fb-200d-1f4bb","👩🏼‍💻":"1f469-1f3fc-200d-1f4bb","👩🏽‍💻":"1f469-1f3fd-200d-1f4bb","👩🏾‍💻":"1f469-1f3fe-200d-1f4bb","👩🏿‍💻":"1f469-1f3ff-200d-1f4bb","👨🏻‍🎤":"1f468-1f3fb-200d-1f3a4","👨🏼‍🎤":"1f468-1f3fc-200d-1f3a4","👨🏽‍🎤":"1f468-1f3fd-200d-1f3a4","👨🏾‍🎤":"1f468-1f3fe-200d-1f3a4","👨🏿‍🎤":"1f468-1f3ff-200d-1f3a4","👩🏻‍🎤":"1f469-1f3fb-200d-1f3a4","👩🏼‍🎤":"1f469-1f3fc-200d-1f3a4","👩🏽‍🎤":"1f469-1f3fd-200d-1f3a4","👩🏾‍🎤":"1f469-1f3fe-200d-1f3a4","👩🏿‍🎤":"1f469-1f3ff-200d-1f3a4","👨🏻‍🎨":"1f468-1f3fb-200d-1f3a8","👨🏼‍🎨":"1f468-1f3fc-200d-1f3a8","👨🏽‍🎨":"1f468-1f3fd-200d-1f3a8","👨🏾‍🎨":"1f468-1f3fe-200d-1f3a8","👨🏿‍🎨":"1f468-1f3ff-200d-1f3a8","👩🏻‍🎨":"1f469-1f3fb-200d-1f3a8","👩🏼‍🎨":"1f469-1f3fc-200d-1f3a8","👩🏽‍🎨":"1f469-1f3fd-200d-1f3a8","👩🏾‍🎨":"1f469-1f3fe-200d-1f3a8","👩🏿‍🎨":"1f469-1f3ff-200d-1f3a8","👨‍✈️":"1f468-200d-2708-fe0f","👨🏻‍✈":"1f468-1f3fb-200d-2708-fe0f","👨🏼‍✈":"1f468-1f3fc-200d-2708-fe0f","👨🏽‍✈":"1f468-1f3fd-200d-2708-fe0f","👨🏾‍✈":"1f468-1f3fe-200d-2708-fe0f","👨🏿‍✈":"1f468-1f3ff-200d-2708-fe0f","👩‍✈️":"1f469-200d-2708-fe0f","👩🏻‍✈":"1f469-1f3fb-200d-2708-fe0f","👩🏼‍✈":"1f469-1f3fc-200d-2708-fe0f","👩🏽‍✈":"1f469-1f3fd-200d-2708-fe0f","👩🏾‍✈":"1f469-1f3fe-200d-2708-fe0f","👩🏿‍✈":"1f469-1f3ff-200d-2708-fe0f","👨🏻‍🚀":"1f468-1f3fb-200d-1f680","👨🏼‍🚀":"1f468-1f3fc-200d-1f680","👨🏽‍🚀":"1f468-1f3fd-200d-1f680","👨🏾‍🚀":"1f468-1f3fe-200d-1f680","👨🏿‍🚀":"1f468-1f3ff-200d-1f680","👩🏻‍🚀":"1f469-1f3fb-200d-1f680","👩🏼‍🚀":"1f469-1f3fc-200d-1f680","👩🏽‍🚀":"1f469-1f3fd-200d-1f680","👩🏾‍🚀":"1f469-1f3fe-200d-1f680","👩🏿‍🚀":"1f469-1f3ff-200d-1f680","👨🏻‍🚒":"1f468-1f3fb-200d-1f692","👨🏼‍🚒":"1f468-1f3fc-200d-1f692","👨🏽‍🚒":"1f468-1f3fd-200d-1f692","👨🏾‍🚒":"1f468-1f3fe-200d-1f692","👨🏿‍🚒":"1f468-1f3ff-200d-1f692","👩🏻‍🚒":"1f469-1f3fb-200d-1f692","👩🏼‍🚒":"1f469-1f3fc-200d-1f692","👩🏽‍🚒":"1f469-1f3fd-200d-1f692","👩🏾‍🚒":"1f469-1f3fe-200d-1f692","👩🏿‍🚒":"1f469-1f3ff-200d-1f692","👮‍♂️":"1f46e-200d-2642-fe0f","👮🏻‍♂":"1f46e-1f3fb-200d-2642-fe0f","👮🏼‍♂":"1f46e-1f3fc-200d-2642-fe0f","👮🏽‍♂":"1f46e-1f3fd-200d-2642-fe0f","👮🏾‍♂":"1f46e-1f3fe-200d-2642-fe0f","👮🏿‍♂":"1f46e-1f3ff-200d-2642-fe0f","👮‍♀️":"1f46e-200d-2640-fe0f","👮🏻‍♀":"1f46e-1f3fb-200d-2640-fe0f","👮🏼‍♀":"1f46e-1f3fc-200d-2640-fe0f","👮🏽‍♀":"1f46e-1f3fd-200d-2640-fe0f","👮🏾‍♀":"1f46e-1f3fe-200d-2640-fe0f","👮🏿‍♀":"1f46e-1f3ff-200d-2640-fe0f","🕵‍♂️":"1f575-fe0f-200d-2642-fe0f","🕵️‍♂":"1f575-fe0f-200d-2642-fe0f","🕵🏻‍♂":"1f575-1f3fb-200d-2642-fe0f","🕵🏼‍♂":"1f575-1f3fc-200d-2642-fe0f","🕵🏽‍♂":"1f575-1f3fd-200d-2642-fe0f","🕵🏾‍♂":"1f575-1f3fe-200d-2642-fe0f","🕵🏿‍♂":"1f575-1f3ff-200d-2642-fe0f","🕵‍♀️":"1f575-fe0f-200d-2640-fe0f","🕵️‍♀":"1f575-fe0f-200d-2640-fe0f","🕵🏻‍♀":"1f575-1f3fb-200d-2640-fe0f","🕵🏼‍♀":"1f575-1f3fc-200d-2640-fe0f","🕵🏽‍♀":"1f575-1f3fd-200d-2640-fe0f","🕵🏾‍♀":"1f575-1f3fe-200d-2640-fe0f","🕵🏿‍♀":"1f575-1f3ff-200d-2640-fe0f","💂‍♂️":"1f482-200d-2642-fe0f","💂🏻‍♂":"1f482-1f3fb-200d-2642-fe0f","💂🏼‍♂":"1f482-1f3fc-200d-2642-fe0f","💂🏽‍♂":"1f482-1f3fd-200d-2642-fe0f","💂🏾‍♂":"1f482-1f3fe-200d-2642-fe0f","💂🏿‍♂":"1f482-1f3ff-200d-2642-fe0f","💂‍♀️":"1f482-200d-2640-fe0f","💂🏻‍♀":"1f482-1f3fb-200d-2640-fe0f","💂🏼‍♀":"1f482-1f3fc-200d-2640-fe0f","💂🏽‍♀":"1f482-1f3fd-200d-2640-fe0f","💂🏾‍♀":"1f482-1f3fe-200d-2640-fe0f","💂🏿‍♀":"1f482-1f3ff-200d-2640-fe0f","👷‍♂️":"1f477-200d-2642-fe0f","👷🏻‍♂":"1f477-1f3fb-200d-2642-fe0f","👷🏼‍♂":"1f477-1f3fc-200d-2642-fe0f","👷🏽‍♂":"1f477-1f3fd-200d-2642-fe0f","👷🏾‍♂":"1f477-1f3fe-200d-2642-fe0f","👷🏿‍♂":"1f477-1f3ff-200d-2642-fe0f","👷‍♀️":"1f477-200d-2640-fe0f","👷🏻‍♀":"1f477-1f3fb-200d-2640-fe0f","👷🏼‍♀":"1f477-1f3fc-200d-2640-fe0f","👷🏽‍♀":"1f477-1f3fd-200d-2640-fe0f","👷🏾‍♀":"1f477-1f3fe-200d-2640-fe0f","👷🏿‍♀":"1f477-1f3ff-200d-2640-fe0f","👳‍♂️":"1f473-200d-2642-fe0f","👳🏻‍♂":"1f473-1f3fb-200d-2642-fe0f","👳🏼‍♂":"1f473-1f3fc-200d-2642-fe0f","👳🏽‍♂":"1f473-1f3fd-200d-2642-fe0f","👳🏾‍♂":"1f473-1f3fe-200d-2642-fe0f","👳🏿‍♂":"1f473-1f3ff-200d-2642-fe0f","👳‍♀️":"1f473-200d-2640-fe0f","👳🏻‍♀":"1f473-1f3fb-200d-2640-fe0f","👳🏼‍♀":"1f473-1f3fc-200d-2640-fe0f","👳🏽‍♀":"1f473-1f3fd-200d-2640-fe0f","👳🏾‍♀":"1f473-1f3fe-200d-2640-fe0f","👳🏿‍♀":"1f473-1f3ff-200d-2640-fe0f","👱‍♂️":"1f471-200d-2642-fe0f","👱🏻‍♂":"1f471-1f3fb-200d-2642-fe0f","👱🏼‍♂":"1f471-1f3fc-200d-2642-fe0f","👱🏽‍♂":"1f471-1f3fd-200d-2642-fe0f","👱🏾‍♂":"1f471-1f3fe-200d-2642-fe0f","👱🏿‍♂":"1f471-1f3ff-200d-2642-fe0f","👱‍♀️":"1f471-200d-2640-fe0f","👱🏻‍♀":"1f471-1f3fb-200d-2640-fe0f","👱🏼‍♀":"1f471-1f3fc-200d-2640-fe0f","👱🏽‍♀":"1f471-1f3fd-200d-2640-fe0f","👱🏾‍♀":"1f471-1f3fe-200d-2640-fe0f","👱🏿‍♀":"1f471-1f3ff-200d-2640-fe0f","👨🏻‍🦰":"1f468-1f3fb-200d-1f9b0","👨🏼‍🦰":"1f468-1f3fc-200d-1f9b0","👨🏽‍🦰":"1f468-1f3fd-200d-1f9b0","👨🏾‍🦰":"1f468-1f3fe-200d-1f9b0","👨🏿‍🦰":"1f468-1f3ff-200d-1f9b0","👩🏻‍🦰":"1f469-1f3fb-200d-1f9b0","👩🏼‍🦰":"1f469-1f3fc-200d-1f9b0","👩🏽‍🦰":"1f469-1f3fd-200d-1f9b0","👩🏾‍🦰":"1f469-1f3fe-200d-1f9b0","👩🏿‍🦰":"1f469-1f3ff-200d-1f9b0","👨🏻‍🦱":"1f468-1f3fb-200d-1f9b1","👨🏼‍🦱":"1f468-1f3fc-200d-1f9b1","👨🏽‍🦱":"1f468-1f3fd-200d-1f9b1","👨🏾‍🦱":"1f468-1f3fe-200d-1f9b1","👨🏿‍🦱":"1f468-1f3ff-200d-1f9b1","👩🏻‍🦱":"1f469-1f3fb-200d-1f9b1","👩🏼‍🦱":"1f469-1f3fc-200d-1f9b1","👩🏽‍🦱":"1f469-1f3fd-200d-1f9b1","👩🏾‍🦱":"1f469-1f3fe-200d-1f9b1","👩🏿‍🦱":"1f469-1f3ff-200d-1f9b1","👨🏻‍🦲":"1f468-1f3fb-200d-1f9b2","👨🏼‍🦲":"1f468-1f3fc-200d-1f9b2","👨🏽‍🦲":"1f468-1f3fd-200d-1f9b2","👨🏾‍🦲":"1f468-1f3fe-200d-1f9b2","👨🏿‍🦲":"1f468-1f3ff-200d-1f9b2","👩🏻‍🦲":"1f469-1f3fb-200d-1f9b2","👩🏼‍🦲":"1f469-1f3fc-200d-1f9b2","👩🏽‍🦲":"1f469-1f3fd-200d-1f9b2","👩🏾‍🦲":"1f469-1f3fe-200d-1f9b2","👩🏿‍🦲":"1f469-1f3ff-200d-1f9b2","👨🏻‍🦳":"1f468-1f3fb-200d-1f9b3","👨🏼‍🦳":"1f468-1f3fc-200d-1f9b3","👨🏽‍🦳":"1f468-1f3fd-200d-1f9b3","👨🏾‍🦳":"1f468-1f3fe-200d-1f9b3","👨🏿‍🦳":"1f468-1f3ff-200d-1f9b3","👩🏻‍🦳":"1f469-1f3fb-200d-1f9b3","👩🏼‍🦳":"1f469-1f3fc-200d-1f9b3","👩🏽‍🦳":"1f469-1f3fd-200d-1f9b3","👩🏾‍🦳":"1f469-1f3fe-200d-1f9b3","👩🏿‍🦳":"1f469-1f3ff-200d-1f9b3","🦸‍♀️":"1f9b8-200d-2640-fe0f","🦸🏻‍♀":"1f9b8-1f3fb-200d-2640-fe0f","🦸🏼‍♀":"1f9b8-1f3fc-200d-2640-fe0f","🦸🏽‍♀":"1f9b8-1f3fd-200d-2640-fe0f","🦸🏾‍♀":"1f9b8-1f3fe-200d-2640-fe0f","🦸🏿‍♀":"1f9b8-1f3ff-200d-2640-fe0f","🦸‍♂️":"1f9b8-200d-2642-fe0f","🦸🏻‍♂":"1f9b8-1f3fb-200d-2642-fe0f","🦸🏼‍♂":"1f9b8-1f3fc-200d-2642-fe0f","🦸🏽‍♂":"1f9b8-1f3fd-200d-2642-fe0f","🦸🏾‍♂":"1f9b8-1f3fe-200d-2642-fe0f","🦸🏿‍♂":"1f9b8-1f3ff-200d-2642-fe0f","🦹‍♀️":"1f9b9-200d-2640-fe0f","🦹🏻‍♀":"1f9b9-1f3fb-200d-2640-fe0f","🦹🏼‍♀":"1f9b9-1f3fc-200d-2640-fe0f","🦹🏽‍♀":"1f9b9-1f3fd-200d-2640-fe0f","🦹🏾‍♀":"1f9b9-1f3fe-200d-2640-fe0f","🦹🏿‍♀":"1f9b9-1f3ff-200d-2640-fe0f","🦹‍♂️":"1f9b9-200d-2642-fe0f","🦹🏻‍♂":"1f9b9-1f3fb-200d-2642-fe0f","🦹🏼‍♂":"1f9b9-1f3fc-200d-2642-fe0f","🦹🏽‍♂":"1f9b9-1f3fd-200d-2642-fe0f","🦹🏾‍♂":"1f9b9-1f3fe-200d-2642-fe0f","🦹🏿‍♂":"1f9b9-1f3ff-200d-2642-fe0f","🧙‍♀️":"1f9d9-200d-2640-fe0f","🧙🏻‍♀":"1f9d9-1f3fb-200d-2640-fe0f","🧙🏼‍♀":"1f9d9-1f3fc-200d-2640-fe0f","🧙🏽‍♀":"1f9d9-1f3fd-200d-2640-fe0f","🧙🏾‍♀":"1f9d9-1f3fe-200d-2640-fe0f","🧙🏿‍♀":"1f9d9-1f3ff-200d-2640-fe0f","🧙‍♂️":"1f9d9-200d-2642-fe0f","🧙🏻‍♂":"1f9d9-1f3fb-200d-2642-fe0f","🧙🏼‍♂":"1f9d9-1f3fc-200d-2642-fe0f","🧙🏽‍♂":"1f9d9-1f3fd-200d-2642-fe0f","🧙🏾‍♂":"1f9d9-1f3fe-200d-2642-fe0f","🧙🏿‍♂":"1f9d9-1f3ff-200d-2642-fe0f","🧚‍♀️":"1f9da-200d-2640-fe0f","🧚🏻‍♀":"1f9da-1f3fb-200d-2640-fe0f","🧚🏼‍♀":"1f9da-1f3fc-200d-2640-fe0f","🧚🏽‍♀":"1f9da-1f3fd-200d-2640-fe0f","🧚🏾‍♀":"1f9da-1f3fe-200d-2640-fe0f","🧚🏿‍♀":"1f9da-1f3ff-200d-2640-fe0f","🧚‍♂️":"1f9da-200d-2642-fe0f","🧚🏻‍♂":"1f9da-1f3fb-200d-2642-fe0f","🧚🏼‍♂":"1f9da-1f3fc-200d-2642-fe0f","🧚🏽‍♂":"1f9da-1f3fd-200d-2642-fe0f","🧚🏾‍♂":"1f9da-1f3fe-200d-2642-fe0f","🧚🏿‍♂":"1f9da-1f3ff-200d-2642-fe0f","🧛‍♀️":"1f9db-200d-2640-fe0f","🧛🏻‍♀":"1f9db-1f3fb-200d-2640-fe0f","🧛🏼‍♀":"1f9db-1f3fc-200d-2640-fe0f","🧛🏽‍♀":"1f9db-1f3fd-200d-2640-fe0f","🧛🏾‍♀":"1f9db-1f3fe-200d-2640-fe0f","🧛🏿‍♀":"1f9db-1f3ff-200d-2640-fe0f","🧛‍♂️":"1f9db-200d-2642-fe0f","🧛🏻‍♂":"1f9db-1f3fb-200d-2642-fe0f","🧛🏼‍♂":"1f9db-1f3fc-200d-2642-fe0f","🧛🏽‍♂":"1f9db-1f3fd-200d-2642-fe0f","🧛🏾‍♂":"1f9db-1f3fe-200d-2642-fe0f","🧛🏿‍♂":"1f9db-1f3ff-200d-2642-fe0f","🧜‍♀️":"1f9dc-200d-2640-fe0f","🧜🏻‍♀":"1f9dc-1f3fb-200d-2640-fe0f","🧜🏼‍♀":"1f9dc-1f3fc-200d-2640-fe0f","🧜🏽‍♀":"1f9dc-1f3fd-200d-2640-fe0f","🧜🏾‍♀":"1f9dc-1f3fe-200d-2640-fe0f","🧜🏿‍♀":"1f9dc-1f3ff-200d-2640-fe0f","🧜‍♂️":"1f9dc-200d-2642-fe0f","🧜🏻‍♂":"1f9dc-1f3fb-200d-2642-fe0f","🧜🏼‍♂":"1f9dc-1f3fc-200d-2642-fe0f","🧜🏽‍♂":"1f9dc-1f3fd-200d-2642-fe0f","🧜🏾‍♂":"1f9dc-1f3fe-200d-2642-fe0f","🧜🏿‍♂":"1f9dc-1f3ff-200d-2642-fe0f","🧝‍♀️":"1f9dd-200d-2640-fe0f","🧝🏻‍♀":"1f9dd-1f3fb-200d-2640-fe0f","🧝🏼‍♀":"1f9dd-1f3fc-200d-2640-fe0f","🧝🏽‍♀":"1f9dd-1f3fd-200d-2640-fe0f","🧝🏾‍♀":"1f9dd-1f3fe-200d-2640-fe0f","🧝🏿‍♀":"1f9dd-1f3ff-200d-2640-fe0f","🧝‍♂️":"1f9dd-200d-2642-fe0f","🧝🏻‍♂":"1f9dd-1f3fb-200d-2642-fe0f","🧝🏼‍♂":"1f9dd-1f3fc-200d-2642-fe0f","🧝🏽‍♂":"1f9dd-1f3fd-200d-2642-fe0f","🧝🏾‍♂":"1f9dd-1f3fe-200d-2642-fe0f","🧝🏿‍♂":"1f9dd-1f3ff-200d-2642-fe0f","🧞‍♀️":"1f9de-200d-2640-fe0f","🧞‍♂️":"1f9de-200d-2642-fe0f","🧟‍♀️":"1f9df-200d-2640-fe0f","🧟‍♂️":"1f9df-200d-2642-fe0f","🙍‍♂️":"1f64d-200d-2642-fe0f","🙍🏻‍♂":"1f64d-1f3fb-200d-2642-fe0f","🙍🏼‍♂":"1f64d-1f3fc-200d-2642-fe0f","🙍🏽‍♂":"1f64d-1f3fd-200d-2642-fe0f","🙍🏾‍♂":"1f64d-1f3fe-200d-2642-fe0f","🙍🏿‍♂":"1f64d-1f3ff-200d-2642-fe0f","🙍‍♀️":"1f64d-200d-2640-fe0f","🙍🏻‍♀":"1f64d-1f3fb-200d-2640-fe0f","🙍🏼‍♀":"1f64d-1f3fc-200d-2640-fe0f","🙍🏽‍♀":"1f64d-1f3fd-200d-2640-fe0f","🙍🏾‍♀":"1f64d-1f3fe-200d-2640-fe0f","🙍🏿‍♀":"1f64d-1f3ff-200d-2640-fe0f","🙎‍♂️":"1f64e-200d-2642-fe0f","🙎🏻‍♂":"1f64e-1f3fb-200d-2642-fe0f","🙎🏼‍♂":"1f64e-1f3fc-200d-2642-fe0f","🙎🏽‍♂":"1f64e-1f3fd-200d-2642-fe0f","🙎🏾‍♂":"1f64e-1f3fe-200d-2642-fe0f","🙎🏿‍♂":"1f64e-1f3ff-200d-2642-fe0f","🙎‍♀️":"1f64e-200d-2640-fe0f","🙎🏻‍♀":"1f64e-1f3fb-200d-2640-fe0f","🙎🏼‍♀":"1f64e-1f3fc-200d-2640-fe0f","🙎🏽‍♀":"1f64e-1f3fd-200d-2640-fe0f","🙎🏾‍♀":"1f64e-1f3fe-200d-2640-fe0f","🙎🏿‍♀":"1f64e-1f3ff-200d-2640-fe0f","🙅‍♂️":"1f645-200d-2642-fe0f","🙅🏻‍♂":"1f645-1f3fb-200d-2642-fe0f","🙅🏼‍♂":"1f645-1f3fc-200d-2642-fe0f","🙅🏽‍♂":"1f645-1f3fd-200d-2642-fe0f","🙅🏾‍♂":"1f645-1f3fe-200d-2642-fe0f","🙅🏿‍♂":"1f645-1f3ff-200d-2642-fe0f","🙅‍♀️":"1f645-200d-2640-fe0f","🙅🏻‍♀":"1f645-1f3fb-200d-2640-fe0f","🙅🏼‍♀":"1f645-1f3fc-200d-2640-fe0f","🙅🏽‍♀":"1f645-1f3fd-200d-2640-fe0f","🙅🏾‍♀":"1f645-1f3fe-200d-2640-fe0f","🙅🏿‍♀":"1f645-1f3ff-200d-2640-fe0f","🙆‍♂️":"1f646-200d-2642-fe0f","🙆🏻‍♂":"1f646-1f3fb-200d-2642-fe0f","🙆🏼‍♂":"1f646-1f3fc-200d-2642-fe0f","🙆🏽‍♂":"1f646-1f3fd-200d-2642-fe0f","🙆🏾‍♂":"1f646-1f3fe-200d-2642-fe0f","🙆🏿‍♂":"1f646-1f3ff-200d-2642-fe0f","🙆‍♀️":"1f646-200d-2640-fe0f","🙆🏻‍♀":"1f646-1f3fb-200d-2640-fe0f","🙆🏼‍♀":"1f646-1f3fc-200d-2640-fe0f","🙆🏽‍♀":"1f646-1f3fd-200d-2640-fe0f","🙆🏾‍♀":"1f646-1f3fe-200d-2640-fe0f","🙆🏿‍♀":"1f646-1f3ff-200d-2640-fe0f","💁‍♂️":"1f481-200d-2642-fe0f","💁🏻‍♂":"1f481-1f3fb-200d-2642-fe0f","💁🏼‍♂":"1f481-1f3fc-200d-2642-fe0f","💁🏽‍♂":"1f481-1f3fd-200d-2642-fe0f","💁🏾‍♂":"1f481-1f3fe-200d-2642-fe0f","💁🏿‍♂":"1f481-1f3ff-200d-2642-fe0f","💁‍♀️":"1f481-200d-2640-fe0f","💁🏻‍♀":"1f481-1f3fb-200d-2640-fe0f","💁🏼‍♀":"1f481-1f3fc-200d-2640-fe0f","💁🏽‍♀":"1f481-1f3fd-200d-2640-fe0f","💁🏾‍♀":"1f481-1f3fe-200d-2640-fe0f","💁🏿‍♀":"1f481-1f3ff-200d-2640-fe0f","🙋‍♂️":"1f64b-200d-2642-fe0f","🙋🏻‍♂":"1f64b-1f3fb-200d-2642-fe0f","🙋🏼‍♂":"1f64b-1f3fc-200d-2642-fe0f","🙋🏽‍♂":"1f64b-1f3fd-200d-2642-fe0f","🙋🏾‍♂":"1f64b-1f3fe-200d-2642-fe0f","🙋🏿‍♂":"1f64b-1f3ff-200d-2642-fe0f","🙋‍♀️":"1f64b-200d-2640-fe0f","🙋🏻‍♀":"1f64b-1f3fb-200d-2640-fe0f","🙋🏼‍♀":"1f64b-1f3fc-200d-2640-fe0f","🙋🏽‍♀":"1f64b-1f3fd-200d-2640-fe0f","🙋🏾‍♀":"1f64b-1f3fe-200d-2640-fe0f","🙋🏿‍♀":"1f64b-1f3ff-200d-2640-fe0f","🙇‍♂️":"1f647-200d-2642-fe0f","🙇🏻‍♂":"1f647-1f3fb-200d-2642-fe0f","🙇🏼‍♂":"1f647-1f3fc-200d-2642-fe0f","🙇🏽‍♂":"1f647-1f3fd-200d-2642-fe0f","🙇🏾‍♂":"1f647-1f3fe-200d-2642-fe0f","🙇🏿‍♂":"1f647-1f3ff-200d-2642-fe0f","🙇‍♀️":"1f647-200d-2640-fe0f","🙇🏻‍♀":"1f647-1f3fb-200d-2640-fe0f","🙇🏼‍♀":"1f647-1f3fc-200d-2640-fe0f","🙇🏽‍♀":"1f647-1f3fd-200d-2640-fe0f","🙇🏾‍♀":"1f647-1f3fe-200d-2640-fe0f","🙇🏿‍♀":"1f647-1f3ff-200d-2640-fe0f","🤦‍♂️":"1f926-200d-2642-fe0f","🤦🏻‍♂":"1f926-1f3fb-200d-2642-fe0f","🤦🏼‍♂":"1f926-1f3fc-200d-2642-fe0f","🤦🏽‍♂":"1f926-1f3fd-200d-2642-fe0f","🤦🏾‍♂":"1f926-1f3fe-200d-2642-fe0f","🤦🏿‍♂":"1f926-1f3ff-200d-2642-fe0f","🤦‍♀️":"1f926-200d-2640-fe0f","🤦🏻‍♀":"1f926-1f3fb-200d-2640-fe0f","🤦🏼‍♀":"1f926-1f3fc-200d-2640-fe0f","🤦🏽‍♀":"1f926-1f3fd-200d-2640-fe0f","🤦🏾‍♀":"1f926-1f3fe-200d-2640-fe0f","🤦🏿‍♀":"1f926-1f3ff-200d-2640-fe0f","🤷‍♂️":"1f937-200d-2642-fe0f","🤷🏻‍♂":"1f937-1f3fb-200d-2642-fe0f","🤷🏼‍♂":"1f937-1f3fc-200d-2642-fe0f","🤷🏽‍♂":"1f937-1f3fd-200d-2642-fe0f","🤷🏾‍♂":"1f937-1f3fe-200d-2642-fe0f","🤷🏿‍♂":"1f937-1f3ff-200d-2642-fe0f","🤷‍♀️":"1f937-200d-2640-fe0f","🤷🏻‍♀":"1f937-1f3fb-200d-2640-fe0f","🤷🏼‍♀":"1f937-1f3fc-200d-2640-fe0f","🤷🏽‍♀":"1f937-1f3fd-200d-2640-fe0f","🤷🏾‍♀":"1f937-1f3fe-200d-2640-fe0f","🤷🏿‍♀":"1f937-1f3ff-200d-2640-fe0f","💆‍♂️":"1f486-200d-2642-fe0f","💆🏻‍♂":"1f486-1f3fb-200d-2642-fe0f","💆🏼‍♂":"1f486-1f3fc-200d-2642-fe0f","💆🏽‍♂":"1f486-1f3fd-200d-2642-fe0f","💆🏾‍♂":"1f486-1f3fe-200d-2642-fe0f","💆🏿‍♂":"1f486-1f3ff-200d-2642-fe0f","💆‍♀️":"1f486-200d-2640-fe0f","💆🏻‍♀":"1f486-1f3fb-200d-2640-fe0f","💆🏼‍♀":"1f486-1f3fc-200d-2640-fe0f","💆🏽‍♀":"1f486-1f3fd-200d-2640-fe0f","💆🏾‍♀":"1f486-1f3fe-200d-2640-fe0f","💆🏿‍♀":"1f486-1f3ff-200d-2640-fe0f","💇‍♂️":"1f487-200d-2642-fe0f","💇🏻‍♂":"1f487-1f3fb-200d-2642-fe0f","💇🏼‍♂":"1f487-1f3fc-200d-2642-fe0f","💇🏽‍♂":"1f487-1f3fd-200d-2642-fe0f","💇🏾‍♂":"1f487-1f3fe-200d-2642-fe0f","💇🏿‍♂":"1f487-1f3ff-200d-2642-fe0f","💇‍♀️":"1f487-200d-2640-fe0f","💇🏻‍♀":"1f487-1f3fb-200d-2640-fe0f","💇🏼‍♀":"1f487-1f3fc-200d-2640-fe0f","💇🏽‍♀":"1f487-1f3fd-200d-2640-fe0f","💇🏾‍♀":"1f487-1f3fe-200d-2640-fe0f","💇🏿‍♀":"1f487-1f3ff-200d-2640-fe0f","🚶‍♂️":"1f6b6-200d-2642-fe0f","🚶🏻‍♂":"1f6b6-1f3fb-200d-2642-fe0f","🚶🏼‍♂":"1f6b6-1f3fc-200d-2642-fe0f","🚶🏽‍♂":"1f6b6-1f3fd-200d-2642-fe0f","🚶🏾‍♂":"1f6b6-1f3fe-200d-2642-fe0f","🚶🏿‍♂":"1f6b6-1f3ff-200d-2642-fe0f","🚶‍♀️":"1f6b6-200d-2640-fe0f","🚶🏻‍♀":"1f6b6-1f3fb-200d-2640-fe0f","🚶🏼‍♀":"1f6b6-1f3fc-200d-2640-fe0f","🚶🏽‍♀":"1f6b6-1f3fd-200d-2640-fe0f","🚶🏾‍♀":"1f6b6-1f3fe-200d-2640-fe0f","🚶🏿‍♀":"1f6b6-1f3ff-200d-2640-fe0f","🏃‍♂️":"1f3c3-200d-2642-fe0f","🏃🏻‍♂":"1f3c3-1f3fb-200d-2642-fe0f","🏃🏼‍♂":"1f3c3-1f3fc-200d-2642-fe0f","🏃🏽‍♂":"1f3c3-1f3fd-200d-2642-fe0f","🏃🏾‍♂":"1f3c3-1f3fe-200d-2642-fe0f","🏃🏿‍♂":"1f3c3-1f3ff-200d-2642-fe0f","🏃‍♀️":"1f3c3-200d-2640-fe0f","🏃🏻‍♀":"1f3c3-1f3fb-200d-2640-fe0f","🏃🏼‍♀":"1f3c3-1f3fc-200d-2640-fe0f","🏃🏽‍♀":"1f3c3-1f3fd-200d-2640-fe0f","🏃🏾‍♀":"1f3c3-1f3fe-200d-2640-fe0f","🏃🏿‍♀":"1f3c3-1f3ff-200d-2640-fe0f","👯‍♂️":"1f46f-200d-2642-fe0f","👯‍♀️":"1f46f-200d-2640-fe0f","🧖‍♀️":"1f9d6-200d-2640-fe0f","🧖🏻‍♀":"1f9d6-1f3fb-200d-2640-fe0f","🧖🏼‍♀":"1f9d6-1f3fc-200d-2640-fe0f","🧖🏽‍♀":"1f9d6-1f3fd-200d-2640-fe0f","🧖🏾‍♀":"1f9d6-1f3fe-200d-2640-fe0f","🧖🏿‍♀":"1f9d6-1f3ff-200d-2640-fe0f","🧖‍♂️":"1f9d6-200d-2642-fe0f","🧖🏻‍♂":"1f9d6-1f3fb-200d-2642-fe0f","🧖🏼‍♂":"1f9d6-1f3fc-200d-2642-fe0f","🧖🏽‍♂":"1f9d6-1f3fd-200d-2642-fe0f","🧖🏾‍♂":"1f9d6-1f3fe-200d-2642-fe0f","🧖🏿‍♂":"1f9d6-1f3ff-200d-2642-fe0f","🧗‍♀️":"1f9d7-200d-2640-fe0f","🧗🏻‍♀":"1f9d7-1f3fb-200d-2640-fe0f","🧗🏼‍♀":"1f9d7-1f3fc-200d-2640-fe0f","🧗🏽‍♀":"1f9d7-1f3fd-200d-2640-fe0f","🧗🏾‍♀":"1f9d7-1f3fe-200d-2640-fe0f","🧗🏿‍♀":"1f9d7-1f3ff-200d-2640-fe0f","🧗‍♂️":"1f9d7-200d-2642-fe0f","🧗🏻‍♂":"1f9d7-1f3fb-200d-2642-fe0f","🧗🏼‍♂":"1f9d7-1f3fc-200d-2642-fe0f","🧗🏽‍♂":"1f9d7-1f3fd-200d-2642-fe0f","🧗🏾‍♂":"1f9d7-1f3fe-200d-2642-fe0f","🧗🏿‍♂":"1f9d7-1f3ff-200d-2642-fe0f","🧘‍♀️":"1f9d8-200d-2640-fe0f","🧘🏻‍♀":"1f9d8-1f3fb-200d-2640-fe0f","🧘🏼‍♀":"1f9d8-1f3fc-200d-2640-fe0f","🧘🏽‍♀":"1f9d8-1f3fd-200d-2640-fe0f","🧘🏾‍♀":"1f9d8-1f3fe-200d-2640-fe0f","🧘🏿‍♀":"1f9d8-1f3ff-200d-2640-fe0f","🧘‍♂️":"1f9d8-200d-2642-fe0f","🧘🏻‍♂":"1f9d8-1f3fb-200d-2642-fe0f","🧘🏼‍♂":"1f9d8-1f3fc-200d-2642-fe0f","🧘🏽‍♂":"1f9d8-1f3fd-200d-2642-fe0f","🧘🏾‍♂":"1f9d8-1f3fe-200d-2642-fe0f","🧘🏿‍♂":"1f9d8-1f3ff-200d-2642-fe0f","🏌‍♂️":"1f3cc-fe0f-200d-2642-fe0f","🏌️‍♂":"1f3cc-fe0f-200d-2642-fe0f","🏌🏻‍♂":"1f3cc-1f3fb-200d-2642-fe0f","🏌🏼‍♂":"1f3cc-1f3fc-200d-2642-fe0f","🏌🏽‍♂":"1f3cc-1f3fd-200d-2642-fe0f","🏌🏾‍♂":"1f3cc-1f3fe-200d-2642-fe0f","🏌🏿‍♂":"1f3cc-1f3ff-200d-2642-fe0f","🏌‍♀️":"1f3cc-fe0f-200d-2640-fe0f","🏌️‍♀":"1f3cc-fe0f-200d-2640-fe0f","🏌🏻‍♀":"1f3cc-1f3fb-200d-2640-fe0f","🏌🏼‍♀":"1f3cc-1f3fc-200d-2640-fe0f","🏌🏽‍♀":"1f3cc-1f3fd-200d-2640-fe0f","🏌🏾‍♀":"1f3cc-1f3fe-200d-2640-fe0f","🏌🏿‍♀":"1f3cc-1f3ff-200d-2640-fe0f","🏄‍♂️":"1f3c4-200d-2642-fe0f","🏄🏻‍♂":"1f3c4-1f3fb-200d-2642-fe0f","🏄🏼‍♂":"1f3c4-1f3fc-200d-2642-fe0f","🏄🏽‍♂":"1f3c4-1f3fd-200d-2642-fe0f","🏄🏾‍♂":"1f3c4-1f3fe-200d-2642-fe0f","🏄🏿‍♂":"1f3c4-1f3ff-200d-2642-fe0f","🏄‍♀️":"1f3c4-200d-2640-fe0f","🏄🏻‍♀":"1f3c4-1f3fb-200d-2640-fe0f","🏄🏼‍♀":"1f3c4-1f3fc-200d-2640-fe0f","🏄🏽‍♀":"1f3c4-1f3fd-200d-2640-fe0f","🏄🏾‍♀":"1f3c4-1f3fe-200d-2640-fe0f","🏄🏿‍♀":"1f3c4-1f3ff-200d-2640-fe0f","🚣‍♂️":"1f6a3-200d-2642-fe0f","🚣🏻‍♂":"1f6a3-1f3fb-200d-2642-fe0f","🚣🏼‍♂":"1f6a3-1f3fc-200d-2642-fe0f","🚣🏽‍♂":"1f6a3-1f3fd-200d-2642-fe0f","🚣🏾‍♂":"1f6a3-1f3fe-200d-2642-fe0f","🚣🏿‍♂":"1f6a3-1f3ff-200d-2642-fe0f","🚣‍♀️":"1f6a3-200d-2640-fe0f","🚣🏻‍♀":"1f6a3-1f3fb-200d-2640-fe0f","🚣🏼‍♀":"1f6a3-1f3fc-200d-2640-fe0f","🚣🏽‍♀":"1f6a3-1f3fd-200d-2640-fe0f","🚣🏾‍♀":"1f6a3-1f3fe-200d-2640-fe0f","🚣🏿‍♀":"1f6a3-1f3ff-200d-2640-fe0f","🏊‍♂️":"1f3ca-200d-2642-fe0f","🏊🏻‍♂":"1f3ca-1f3fb-200d-2642-fe0f","🏊🏼‍♂":"1f3ca-1f3fc-200d-2642-fe0f","🏊🏽‍♂":"1f3ca-1f3fd-200d-2642-fe0f","🏊🏾‍♂":"1f3ca-1f3fe-200d-2642-fe0f","🏊🏿‍♂":"1f3ca-1f3ff-200d-2642-fe0f","🏊‍♀️":"1f3ca-200d-2640-fe0f","🏊🏻‍♀":"1f3ca-1f3fb-200d-2640-fe0f","🏊🏼‍♀":"1f3ca-1f3fc-200d-2640-fe0f","🏊🏽‍♀":"1f3ca-1f3fd-200d-2640-fe0f","🏊🏾‍♀":"1f3ca-1f3fe-200d-2640-fe0f","🏊🏿‍♀":"1f3ca-1f3ff-200d-2640-fe0f","⛹‍♂️":"26f9-fe0f-200d-2642-fe0f","⛹️‍♂":"26f9-fe0f-200d-2642-fe0f","⛹🏻‍♂":"26f9-1f3fb-200d-2642-fe0f","⛹🏼‍♂":"26f9-1f3fc-200d-2642-fe0f","⛹🏽‍♂":"26f9-1f3fd-200d-2642-fe0f","⛹🏾‍♂":"26f9-1f3fe-200d-2642-fe0f","⛹🏿‍♂":"26f9-1f3ff-200d-2642-fe0f","⛹‍♀️":"26f9-fe0f-200d-2640-fe0f","⛹️‍♀":"26f9-fe0f-200d-2640-fe0f","⛹🏻‍♀":"26f9-1f3fb-200d-2640-fe0f","⛹🏼‍♀":"26f9-1f3fc-200d-2640-fe0f","⛹🏽‍♀":"26f9-1f3fd-200d-2640-fe0f","⛹🏾‍♀":"26f9-1f3fe-200d-2640-fe0f","⛹🏿‍♀":"26f9-1f3ff-200d-2640-fe0f","🏋‍♂️":"1f3cb-fe0f-200d-2642-fe0f","🏋️‍♂":"1f3cb-fe0f-200d-2642-fe0f","🏋🏻‍♂":"1f3cb-1f3fb-200d-2642-fe0f","🏋🏼‍♂":"1f3cb-1f3fc-200d-2642-fe0f","🏋🏽‍♂":"1f3cb-1f3fd-200d-2642-fe0f","🏋🏾‍♂":"1f3cb-1f3fe-200d-2642-fe0f","🏋🏿‍♂":"1f3cb-1f3ff-200d-2642-fe0f","🏋‍♀️":"1f3cb-fe0f-200d-2640-fe0f","🏋️‍♀":"1f3cb-fe0f-200d-2640-fe0f","🏋🏻‍♀":"1f3cb-1f3fb-200d-2640-fe0f","🏋🏼‍♀":"1f3cb-1f3fc-200d-2640-fe0f","🏋🏽‍♀":"1f3cb-1f3fd-200d-2640-fe0f","🏋🏾‍♀":"1f3cb-1f3fe-200d-2640-fe0f","🏋🏿‍♀":"1f3cb-1f3ff-200d-2640-fe0f","🚴‍♂️":"1f6b4-200d-2642-fe0f","🚴🏻‍♂":"1f6b4-1f3fb-200d-2642-fe0f","🚴🏼‍♂":"1f6b4-1f3fc-200d-2642-fe0f","🚴🏽‍♂":"1f6b4-1f3fd-200d-2642-fe0f","🚴🏾‍♂":"1f6b4-1f3fe-200d-2642-fe0f","🚴🏿‍♂":"1f6b4-1f3ff-200d-2642-fe0f","🚴‍♀️":"1f6b4-200d-2640-fe0f","🚴🏻‍♀":"1f6b4-1f3fb-200d-2640-fe0f","🚴🏼‍♀":"1f6b4-1f3fc-200d-2640-fe0f","🚴🏽‍♀":"1f6b4-1f3fd-200d-2640-fe0f","🚴🏾‍♀":"1f6b4-1f3fe-200d-2640-fe0f","🚴🏿‍♀":"1f6b4-1f3ff-200d-2640-fe0f","🚵‍♂️":"1f6b5-200d-2642-fe0f","🚵🏻‍♂":"1f6b5-1f3fb-200d-2642-fe0f","🚵🏼‍♂":"1f6b5-1f3fc-200d-2642-fe0f","🚵🏽‍♂":"1f6b5-1f3fd-200d-2642-fe0f","🚵🏾‍♂":"1f6b5-1f3fe-200d-2642-fe0f","🚵🏿‍♂":"1f6b5-1f3ff-200d-2642-fe0f","🚵‍♀️":"1f6b5-200d-2640-fe0f","🚵🏻‍♀":"1f6b5-1f3fb-200d-2640-fe0f","🚵🏼‍♀":"1f6b5-1f3fc-200d-2640-fe0f","🚵🏽‍♀":"1f6b5-1f3fd-200d-2640-fe0f","🚵🏾‍♀":"1f6b5-1f3fe-200d-2640-fe0f","🚵🏿‍♀":"1f6b5-1f3ff-200d-2640-fe0f","🤸‍♂️":"1f938-200d-2642-fe0f","🤸🏻‍♂":"1f938-1f3fb-200d-2642-fe0f","🤸🏼‍♂":"1f938-1f3fc-200d-2642-fe0f","🤸🏽‍♂":"1f938-1f3fd-200d-2642-fe0f","🤸🏾‍♂":"1f938-1f3fe-200d-2642-fe0f","🤸🏿‍♂":"1f938-1f3ff-200d-2642-fe0f","🤸‍♀️":"1f938-200d-2640-fe0f","🤸🏻‍♀":"1f938-1f3fb-200d-2640-fe0f","🤸🏼‍♀":"1f938-1f3fc-200d-2640-fe0f","🤸🏽‍♀":"1f938-1f3fd-200d-2640-fe0f","🤸🏾‍♀":"1f938-1f3fe-200d-2640-fe0f","🤸🏿‍♀":"1f938-1f3ff-200d-2640-fe0f","🤼‍♂️":"1f93c-200d-2642-fe0f","🤼‍♀️":"1f93c-200d-2640-fe0f","🤽‍♂️":"1f93d-200d-2642-fe0f","🤽🏻‍♂":"1f93d-1f3fb-200d-2642-fe0f","🤽🏼‍♂":"1f93d-1f3fc-200d-2642-fe0f","🤽🏽‍♂":"1f93d-1f3fd-200d-2642-fe0f","🤽🏾‍♂":"1f93d-1f3fe-200d-2642-fe0f","🤽🏿‍♂":"1f93d-1f3ff-200d-2642-fe0f","🤽‍♀️":"1f93d-200d-2640-fe0f","🤽🏻‍♀":"1f93d-1f3fb-200d-2640-fe0f","🤽🏼‍♀":"1f93d-1f3fc-200d-2640-fe0f","🤽🏽‍♀":"1f93d-1f3fd-200d-2640-fe0f","🤽🏾‍♀":"1f93d-1f3fe-200d-2640-fe0f","🤽🏿‍♀":"1f93d-1f3ff-200d-2640-fe0f","🤾‍♂️":"1f93e-200d-2642-fe0f","🤾🏻‍♂":"1f93e-1f3fb-200d-2642-fe0f","🤾🏼‍♂":"1f93e-1f3fc-200d-2642-fe0f","🤾🏽‍♂":"1f93e-1f3fd-200d-2642-fe0f","🤾🏾‍♂":"1f93e-1f3fe-200d-2642-fe0f","🤾🏿‍♂":"1f93e-1f3ff-200d-2642-fe0f","🤾‍♀️":"1f93e-200d-2640-fe0f","🤾🏻‍♀":"1f93e-1f3fb-200d-2640-fe0f","🤾🏼‍♀":"1f93e-1f3fc-200d-2640-fe0f","🤾🏽‍♀":"1f93e-1f3fd-200d-2640-fe0f","🤾🏾‍♀":"1f93e-1f3fe-200d-2640-fe0f","🤾🏿‍♀":"1f93e-1f3ff-200d-2640-fe0f","🤹‍♂️":"1f939-200d-2642-fe0f","🤹🏻‍♂":"1f939-1f3fb-200d-2642-fe0f","🤹🏼‍♂":"1f939-1f3fc-200d-2642-fe0f","🤹🏽‍♂":"1f939-1f3fd-200d-2642-fe0f","🤹🏾‍♂":"1f939-1f3fe-200d-2642-fe0f","🤹🏿‍♂":"1f939-1f3ff-200d-2642-fe0f","🤹‍♀️":"1f939-200d-2640-fe0f","🤹🏻‍♀":"1f939-1f3fb-200d-2640-fe0f","🤹🏼‍♀":"1f939-1f3fc-200d-2640-fe0f","🤹🏽‍♀":"1f939-1f3fd-200d-2640-fe0f","🤹🏾‍♀":"1f939-1f3fe-200d-2640-fe0f","🤹🏿‍♀":"1f939-1f3ff-200d-2640-fe0f","👁‍🗨️":"1f441-200d-1f5e8","👁️‍🗨":"1f441-200d-1f5e8","🏳️‍🌈":"1f3f3-fe0f-200d-1f308","🏴‍☠️":"1f3f4-200d-2620-fe0f","👨🏻‍⚕️":"1f468-1f3fb-200d-2695-fe0f","👨🏼‍⚕️":"1f468-1f3fc-200d-2695-fe0f","👨🏽‍⚕️":"1f468-1f3fd-200d-2695-fe0f","👨🏾‍⚕️":"1f468-1f3fe-200d-2695-fe0f","👨🏿‍⚕️":"1f468-1f3ff-200d-2695-fe0f","👩🏻‍⚕️":"1f469-1f3fb-200d-2695-fe0f","👩🏼‍⚕️":"1f469-1f3fc-200d-2695-fe0f","👩🏽‍⚕️":"1f469-1f3fd-200d-2695-fe0f","👩🏾‍⚕️":"1f469-1f3fe-200d-2695-fe0f","👩🏿‍⚕️":"1f469-1f3ff-200d-2695-fe0f","👨🏻‍⚖️":"1f468-1f3fb-200d-2696-fe0f","👨🏼‍⚖️":"1f468-1f3fc-200d-2696-fe0f","👨🏽‍⚖️":"1f468-1f3fd-200d-2696-fe0f","👨🏾‍⚖️":"1f468-1f3fe-200d-2696-fe0f","👨🏿‍⚖️":"1f468-1f3ff-200d-2696-fe0f","👩🏻‍⚖️":"1f469-1f3fb-200d-2696-fe0f","👩🏼‍⚖️":"1f469-1f3fc-200d-2696-fe0f","👩🏽‍⚖️":"1f469-1f3fd-200d-2696-fe0f","👩🏾‍⚖️":"1f469-1f3fe-200d-2696-fe0f","👩🏿‍⚖️":"1f469-1f3ff-200d-2696-fe0f","👨🏻‍✈️":"1f468-1f3fb-200d-2708-fe0f","👨🏼‍✈️":"1f468-1f3fc-200d-2708-fe0f","👨🏽‍✈️":"1f468-1f3fd-200d-2708-fe0f","👨🏾‍✈️":"1f468-1f3fe-200d-2708-fe0f","👨🏿‍✈️":"1f468-1f3ff-200d-2708-fe0f","👩🏻‍✈️":"1f469-1f3fb-200d-2708-fe0f","👩🏼‍✈️":"1f469-1f3fc-200d-2708-fe0f","👩🏽‍✈️":"1f469-1f3fd-200d-2708-fe0f","👩🏾‍✈️":"1f469-1f3fe-200d-2708-fe0f","👩🏿‍✈️":"1f469-1f3ff-200d-2708-fe0f","👮🏻‍♂️":"1f46e-1f3fb-200d-2642-fe0f","👮🏼‍♂️":"1f46e-1f3fc-200d-2642-fe0f","👮🏽‍♂️":"1f46e-1f3fd-200d-2642-fe0f","👮🏾‍♂️":"1f46e-1f3fe-200d-2642-fe0f","👮🏿‍♂️":"1f46e-1f3ff-200d-2642-fe0f","👮🏻‍♀️":"1f46e-1f3fb-200d-2640-fe0f","👮🏼‍♀️":"1f46e-1f3fc-200d-2640-fe0f","👮🏽‍♀️":"1f46e-1f3fd-200d-2640-fe0f","👮🏾‍♀️":"1f46e-1f3fe-200d-2640-fe0f","👮🏿‍♀️":"1f46e-1f3ff-200d-2640-fe0f","🕵️‍♂️":"1f575-fe0f-200d-2642-fe0f","🕵🏻‍♂️":"1f575-1f3fb-200d-2642-fe0f","🕵🏼‍♂️":"1f575-1f3fc-200d-2642-fe0f","🕵🏽‍♂️":"1f575-1f3fd-200d-2642-fe0f","🕵🏾‍♂️":"1f575-1f3fe-200d-2642-fe0f","🕵🏿‍♂️":"1f575-1f3ff-200d-2642-fe0f","🕵️‍♀️":"1f575-fe0f-200d-2640-fe0f","🕵🏻‍♀️":"1f575-1f3fb-200d-2640-fe0f","🕵🏼‍♀️":"1f575-1f3fc-200d-2640-fe0f","🕵🏽‍♀️":"1f575-1f3fd-200d-2640-fe0f","🕵🏾‍♀️":"1f575-1f3fe-200d-2640-fe0f","🕵🏿‍♀️":"1f575-1f3ff-200d-2640-fe0f","💂🏻‍♂️":"1f482-1f3fb-200d-2642-fe0f","💂🏼‍♂️":"1f482-1f3fc-200d-2642-fe0f","💂🏽‍♂️":"1f482-1f3fd-200d-2642-fe0f","💂🏾‍♂️":"1f482-1f3fe-200d-2642-fe0f","💂🏿‍♂️":"1f482-1f3ff-200d-2642-fe0f","💂🏻‍♀️":"1f482-1f3fb-200d-2640-fe0f","💂🏼‍♀️":"1f482-1f3fc-200d-2640-fe0f","💂🏽‍♀️":"1f482-1f3fd-200d-2640-fe0f","💂🏾‍♀️":"1f482-1f3fe-200d-2640-fe0f","💂🏿‍♀️":"1f482-1f3ff-200d-2640-fe0f","👷🏻‍♂️":"1f477-1f3fb-200d-2642-fe0f","👷🏼‍♂️":"1f477-1f3fc-200d-2642-fe0f","👷🏽‍♂️":"1f477-1f3fd-200d-2642-fe0f","👷🏾‍♂️":"1f477-1f3fe-200d-2642-fe0f","👷🏿‍♂️":"1f477-1f3ff-200d-2642-fe0f","👷🏻‍♀️":"1f477-1f3fb-200d-2640-fe0f","👷🏼‍♀️":"1f477-1f3fc-200d-2640-fe0f","👷🏽‍♀️":"1f477-1f3fd-200d-2640-fe0f","👷🏾‍♀️":"1f477-1f3fe-200d-2640-fe0f","👷🏿‍♀️":"1f477-1f3ff-200d-2640-fe0f","👳🏻‍♂️":"1f473-1f3fb-200d-2642-fe0f","👳🏼‍♂️":"1f473-1f3fc-200d-2642-fe0f","👳🏽‍♂️":"1f473-1f3fd-200d-2642-fe0f","👳🏾‍♂️":"1f473-1f3fe-200d-2642-fe0f","👳🏿‍♂️":"1f473-1f3ff-200d-2642-fe0f","👳🏻‍♀️":"1f473-1f3fb-200d-2640-fe0f","👳🏼‍♀️":"1f473-1f3fc-200d-2640-fe0f","👳🏽‍♀️":"1f473-1f3fd-200d-2640-fe0f","👳🏾‍♀️":"1f473-1f3fe-200d-2640-fe0f","👳🏿‍♀️":"1f473-1f3ff-200d-2640-fe0f","👱🏻‍♂️":"1f471-1f3fb-200d-2642-fe0f","👱🏼‍♂️":"1f471-1f3fc-200d-2642-fe0f","👱🏽‍♂️":"1f471-1f3fd-200d-2642-fe0f","👱🏾‍♂️":"1f471-1f3fe-200d-2642-fe0f","👱🏿‍♂️":"1f471-1f3ff-200d-2642-fe0f","👱🏻‍♀️":"1f471-1f3fb-200d-2640-fe0f","👱🏼‍♀️":"1f471-1f3fc-200d-2640-fe0f","👱🏽‍♀️":"1f471-1f3fd-200d-2640-fe0f","👱🏾‍♀️":"1f471-1f3fe-200d-2640-fe0f","👱🏿‍♀️":"1f471-1f3ff-200d-2640-fe0f","🦸🏻‍♀️":"1f9b8-1f3fb-200d-2640-fe0f","🦸🏼‍♀️":"1f9b8-1f3fc-200d-2640-fe0f","🦸🏽‍♀️":"1f9b8-1f3fd-200d-2640-fe0f","🦸🏾‍♀️":"1f9b8-1f3fe-200d-2640-fe0f","🦸🏿‍♀️":"1f9b8-1f3ff-200d-2640-fe0f","🦸🏻‍♂️":"1f9b8-1f3fb-200d-2642-fe0f","🦸🏼‍♂️":"1f9b8-1f3fc-200d-2642-fe0f","🦸🏽‍♂️":"1f9b8-1f3fd-200d-2642-fe0f","🦸🏾‍♂️":"1f9b8-1f3fe-200d-2642-fe0f","🦸🏿‍♂️":"1f9b8-1f3ff-200d-2642-fe0f","🦹🏻‍♀️":"1f9b9-1f3fb-200d-2640-fe0f","🦹🏼‍♀️":"1f9b9-1f3fc-200d-2640-fe0f","🦹🏽‍♀️":"1f9b9-1f3fd-200d-2640-fe0f","🦹🏾‍♀️":"1f9b9-1f3fe-200d-2640-fe0f","🦹🏿‍♀️":"1f9b9-1f3ff-200d-2640-fe0f","🦹🏻‍♂️":"1f9b9-1f3fb-200d-2642-fe0f","🦹🏼‍♂️":"1f9b9-1f3fc-200d-2642-fe0f","🦹🏽‍♂️":"1f9b9-1f3fd-200d-2642-fe0f","🦹🏾‍♂️":"1f9b9-1f3fe-200d-2642-fe0f","🦹🏿‍♂️":"1f9b9-1f3ff-200d-2642-fe0f","🧙🏻‍♀️":"1f9d9-1f3fb-200d-2640-fe0f","🧙🏼‍♀️":"1f9d9-1f3fc-200d-2640-fe0f","🧙🏽‍♀️":"1f9d9-1f3fd-200d-2640-fe0f","🧙🏾‍♀️":"1f9d9-1f3fe-200d-2640-fe0f","🧙🏿‍♀️":"1f9d9-1f3ff-200d-2640-fe0f","🧙🏻‍♂️":"1f9d9-1f3fb-200d-2642-fe0f","🧙🏼‍♂️":"1f9d9-1f3fc-200d-2642-fe0f","🧙🏽‍♂️":"1f9d9-1f3fd-200d-2642-fe0f","🧙🏾‍♂️":"1f9d9-1f3fe-200d-2642-fe0f","🧙🏿‍♂️":"1f9d9-1f3ff-200d-2642-fe0f","🧚🏻‍♀️":"1f9da-1f3fb-200d-2640-fe0f","🧚🏼‍♀️":"1f9da-1f3fc-200d-2640-fe0f","🧚🏽‍♀️":"1f9da-1f3fd-200d-2640-fe0f","🧚🏾‍♀️":"1f9da-1f3fe-200d-2640-fe0f","🧚🏿‍♀️":"1f9da-1f3ff-200d-2640-fe0f","🧚🏻‍♂️":"1f9da-1f3fb-200d-2642-fe0f","🧚🏼‍♂️":"1f9da-1f3fc-200d-2642-fe0f","🧚🏽‍♂️":"1f9da-1f3fd-200d-2642-fe0f","🧚🏾‍♂️":"1f9da-1f3fe-200d-2642-fe0f","🧚🏿‍♂️":"1f9da-1f3ff-200d-2642-fe0f","🧛🏻‍♀️":"1f9db-1f3fb-200d-2640-fe0f","🧛🏼‍♀️":"1f9db-1f3fc-200d-2640-fe0f","🧛🏽‍♀️":"1f9db-1f3fd-200d-2640-fe0f","🧛🏾‍♀️":"1f9db-1f3fe-200d-2640-fe0f","🧛🏿‍♀️":"1f9db-1f3ff-200d-2640-fe0f","🧛🏻‍♂️":"1f9db-1f3fb-200d-2642-fe0f","🧛🏼‍♂️":"1f9db-1f3fc-200d-2642-fe0f","🧛🏽‍♂️":"1f9db-1f3fd-200d-2642-fe0f","🧛🏾‍♂️":"1f9db-1f3fe-200d-2642-fe0f","🧛🏿‍♂️":"1f9db-1f3ff-200d-2642-fe0f","🧜🏻‍♀️":"1f9dc-1f3fb-200d-2640-fe0f","🧜🏼‍♀️":"1f9dc-1f3fc-200d-2640-fe0f","🧜🏽‍♀️":"1f9dc-1f3fd-200d-2640-fe0f","🧜🏾‍♀️":"1f9dc-1f3fe-200d-2640-fe0f","🧜🏿‍♀️":"1f9dc-1f3ff-200d-2640-fe0f","🧜🏻‍♂️":"1f9dc-1f3fb-200d-2642-fe0f","🧜🏼‍♂️":"1f9dc-1f3fc-200d-2642-fe0f","🧜🏽‍♂️":"1f9dc-1f3fd-200d-2642-fe0f","🧜🏾‍♂️":"1f9dc-1f3fe-200d-2642-fe0f","🧜🏿‍♂️":"1f9dc-1f3ff-200d-2642-fe0f","🧝🏻‍♀️":"1f9dd-1f3fb-200d-2640-fe0f","🧝🏼‍♀️":"1f9dd-1f3fc-200d-2640-fe0f","🧝🏽‍♀️":"1f9dd-1f3fd-200d-2640-fe0f","🧝🏾‍♀️":"1f9dd-1f3fe-200d-2640-fe0f","🧝🏿‍♀️":"1f9dd-1f3ff-200d-2640-fe0f","🧝🏻‍♂️":"1f9dd-1f3fb-200d-2642-fe0f","🧝🏼‍♂️":"1f9dd-1f3fc-200d-2642-fe0f","🧝🏽‍♂️":"1f9dd-1f3fd-200d-2642-fe0f","🧝🏾‍♂️":"1f9dd-1f3fe-200d-2642-fe0f","🧝🏿‍♂️":"1f9dd-1f3ff-200d-2642-fe0f","🙍🏻‍♂️":"1f64d-1f3fb-200d-2642-fe0f","🙍🏼‍♂️":"1f64d-1f3fc-200d-2642-fe0f","🙍🏽‍♂️":"1f64d-1f3fd-200d-2642-fe0f","🙍🏾‍♂️":"1f64d-1f3fe-200d-2642-fe0f","🙍🏿‍♂️":"1f64d-1f3ff-200d-2642-fe0f","🙍🏻‍♀️":"1f64d-1f3fb-200d-2640-fe0f","🙍🏼‍♀️":"1f64d-1f3fc-200d-2640-fe0f","🙍🏽‍♀️":"1f64d-1f3fd-200d-2640-fe0f","🙍🏾‍♀️":"1f64d-1f3fe-200d-2640-fe0f","🙍🏿‍♀️":"1f64d-1f3ff-200d-2640-fe0f","🙎🏻‍♂️":"1f64e-1f3fb-200d-2642-fe0f","🙎🏼‍♂️":"1f64e-1f3fc-200d-2642-fe0f","🙎🏽‍♂️":"1f64e-1f3fd-200d-2642-fe0f","🙎🏾‍♂️":"1f64e-1f3fe-200d-2642-fe0f","🙎🏿‍♂️":"1f64e-1f3ff-200d-2642-fe0f","🙎🏻‍♀️":"1f64e-1f3fb-200d-2640-fe0f","🙎🏼‍♀️":"1f64e-1f3fc-200d-2640-fe0f","🙎🏽‍♀️":"1f64e-1f3fd-200d-2640-fe0f","🙎🏾‍♀️":"1f64e-1f3fe-200d-2640-fe0f","🙎🏿‍♀️":"1f64e-1f3ff-200d-2640-fe0f","🙅🏻‍♂️":"1f645-1f3fb-200d-2642-fe0f","🙅🏼‍♂️":"1f645-1f3fc-200d-2642-fe0f","🙅🏽‍♂️":"1f645-1f3fd-200d-2642-fe0f","🙅🏾‍♂️":"1f645-1f3fe-200d-2642-fe0f","🙅🏿‍♂️":"1f645-1f3ff-200d-2642-fe0f","🙅🏻‍♀️":"1f645-1f3fb-200d-2640-fe0f","🙅🏼‍♀️":"1f645-1f3fc-200d-2640-fe0f","🙅🏽‍♀️":"1f645-1f3fd-200d-2640-fe0f","🙅🏾‍♀️":"1f645-1f3fe-200d-2640-fe0f","🙅🏿‍♀️":"1f645-1f3ff-200d-2640-fe0f","🙆🏻‍♂️":"1f646-1f3fb-200d-2642-fe0f","🙆🏼‍♂️":"1f646-1f3fc-200d-2642-fe0f","🙆🏽‍♂️":"1f646-1f3fd-200d-2642-fe0f","🙆🏾‍♂️":"1f646-1f3fe-200d-2642-fe0f","🙆🏿‍♂️":"1f646-1f3ff-200d-2642-fe0f","🙆🏻‍♀️":"1f646-1f3fb-200d-2640-fe0f","🙆🏼‍♀️":"1f646-1f3fc-200d-2640-fe0f","🙆🏽‍♀️":"1f646-1f3fd-200d-2640-fe0f","🙆🏾‍♀️":"1f646-1f3fe-200d-2640-fe0f","🙆🏿‍♀️":"1f646-1f3ff-200d-2640-fe0f","💁🏻‍♂️":"1f481-1f3fb-200d-2642-fe0f","💁🏼‍♂️":"1f481-1f3fc-200d-2642-fe0f","💁🏽‍♂️":"1f481-1f3fd-200d-2642-fe0f","💁🏾‍♂️":"1f481-1f3fe-200d-2642-fe0f","💁🏿‍♂️":"1f481-1f3ff-200d-2642-fe0f","💁🏻‍♀️":"1f481-1f3fb-200d-2640-fe0f","💁🏼‍♀️":"1f481-1f3fc-200d-2640-fe0f","💁🏽‍♀️":"1f481-1f3fd-200d-2640-fe0f","💁🏾‍♀️":"1f481-1f3fe-200d-2640-fe0f","💁🏿‍♀️":"1f481-1f3ff-200d-2640-fe0f","🙋🏻‍♂️":"1f64b-1f3fb-200d-2642-fe0f","🙋🏼‍♂️":"1f64b-1f3fc-200d-2642-fe0f","🙋🏽‍♂️":"1f64b-1f3fd-200d-2642-fe0f","🙋🏾‍♂️":"1f64b-1f3fe-200d-2642-fe0f","🙋🏿‍♂️":"1f64b-1f3ff-200d-2642-fe0f","🙋🏻‍♀️":"1f64b-1f3fb-200d-2640-fe0f","🙋🏼‍♀️":"1f64b-1f3fc-200d-2640-fe0f","🙋🏽‍♀️":"1f64b-1f3fd-200d-2640-fe0f","🙋🏾‍♀️":"1f64b-1f3fe-200d-2640-fe0f","🙋🏿‍♀️":"1f64b-1f3ff-200d-2640-fe0f","🙇🏻‍♂️":"1f647-1f3fb-200d-2642-fe0f","🙇🏼‍♂️":"1f647-1f3fc-200d-2642-fe0f","🙇🏽‍♂️":"1f647-1f3fd-200d-2642-fe0f","🙇🏾‍♂️":"1f647-1f3fe-200d-2642-fe0f","🙇🏿‍♂️":"1f647-1f3ff-200d-2642-fe0f","🙇🏻‍♀️":"1f647-1f3fb-200d-2640-fe0f","🙇🏼‍♀️":"1f647-1f3fc-200d-2640-fe0f","🙇🏽‍♀️":"1f647-1f3fd-200d-2640-fe0f","🙇🏾‍♀️":"1f647-1f3fe-200d-2640-fe0f","🙇🏿‍♀️":"1f647-1f3ff-200d-2640-fe0f","🤦🏻‍♂️":"1f926-1f3fb-200d-2642-fe0f","🤦🏼‍♂️":"1f926-1f3fc-200d-2642-fe0f","🤦🏽‍♂️":"1f926-1f3fd-200d-2642-fe0f","🤦🏾‍♂️":"1f926-1f3fe-200d-2642-fe0f","🤦🏿‍♂️":"1f926-1f3ff-200d-2642-fe0f","🤦🏻‍♀️":"1f926-1f3fb-200d-2640-fe0f","🤦🏼‍♀️":"1f926-1f3fc-200d-2640-fe0f","🤦🏽‍♀️":"1f926-1f3fd-200d-2640-fe0f","🤦🏾‍♀️":"1f926-1f3fe-200d-2640-fe0f","🤦🏿‍♀️":"1f926-1f3ff-200d-2640-fe0f","🤷🏻‍♂️":"1f937-1f3fb-200d-2642-fe0f","🤷🏼‍♂️":"1f937-1f3fc-200d-2642-fe0f","🤷🏽‍♂️":"1f937-1f3fd-200d-2642-fe0f","🤷🏾‍♂️":"1f937-1f3fe-200d-2642-fe0f","🤷🏿‍♂️":"1f937-1f3ff-200d-2642-fe0f","🤷🏻‍♀️":"1f937-1f3fb-200d-2640-fe0f","🤷🏼‍♀️":"1f937-1f3fc-200d-2640-fe0f","🤷🏽‍♀️":"1f937-1f3fd-200d-2640-fe0f","🤷🏾‍♀️":"1f937-1f3fe-200d-2640-fe0f","🤷🏿‍♀️":"1f937-1f3ff-200d-2640-fe0f","💆🏻‍♂️":"1f486-1f3fb-200d-2642-fe0f","💆🏼‍♂️":"1f486-1f3fc-200d-2642-fe0f","💆🏽‍♂️":"1f486-1f3fd-200d-2642-fe0f","💆🏾‍♂️":"1f486-1f3fe-200d-2642-fe0f","💆🏿‍♂️":"1f486-1f3ff-200d-2642-fe0f","💆🏻‍♀️":"1f486-1f3fb-200d-2640-fe0f","💆🏼‍♀️":"1f486-1f3fc-200d-2640-fe0f","💆🏽‍♀️":"1f486-1f3fd-200d-2640-fe0f","💆🏾‍♀️":"1f486-1f3fe-200d-2640-fe0f","💆🏿‍♀️":"1f486-1f3ff-200d-2640-fe0f","💇🏻‍♂️":"1f487-1f3fb-200d-2642-fe0f","💇🏼‍♂️":"1f487-1f3fc-200d-2642-fe0f","💇🏽‍♂️":"1f487-1f3fd-200d-2642-fe0f","💇🏾‍♂️":"1f487-1f3fe-200d-2642-fe0f","💇🏿‍♂️":"1f487-1f3ff-200d-2642-fe0f","💇🏻‍♀️":"1f487-1f3fb-200d-2640-fe0f","💇🏼‍♀️":"1f487-1f3fc-200d-2640-fe0f","💇🏽‍♀️":"1f487-1f3fd-200d-2640-fe0f","💇🏾‍♀️":"1f487-1f3fe-200d-2640-fe0f","💇🏿‍♀️":"1f487-1f3ff-200d-2640-fe0f","🚶🏻‍♂️":"1f6b6-1f3fb-200d-2642-fe0f","🚶🏼‍♂️":"1f6b6-1f3fc-200d-2642-fe0f","🚶🏽‍♂️":"1f6b6-1f3fd-200d-2642-fe0f","🚶🏾‍♂️":"1f6b6-1f3fe-200d-2642-fe0f","🚶🏿‍♂️":"1f6b6-1f3ff-200d-2642-fe0f","🚶🏻‍♀️":"1f6b6-1f3fb-200d-2640-fe0f","🚶🏼‍♀️":"1f6b6-1f3fc-200d-2640-fe0f","🚶🏽‍♀️":"1f6b6-1f3fd-200d-2640-fe0f","🚶🏾‍♀️":"1f6b6-1f3fe-200d-2640-fe0f","🚶🏿‍♀️":"1f6b6-1f3ff-200d-2640-fe0f","🏃🏻‍♂️":"1f3c3-1f3fb-200d-2642-fe0f","🏃🏼‍♂️":"1f3c3-1f3fc-200d-2642-fe0f","🏃🏽‍♂️":"1f3c3-1f3fd-200d-2642-fe0f","🏃🏾‍♂️":"1f3c3-1f3fe-200d-2642-fe0f","🏃🏿‍♂️":"1f3c3-1f3ff-200d-2642-fe0f","🏃🏻‍♀️":"1f3c3-1f3fb-200d-2640-fe0f","🏃🏼‍♀️":"1f3c3-1f3fc-200d-2640-fe0f","🏃🏽‍♀️":"1f3c3-1f3fd-200d-2640-fe0f","🏃🏾‍♀️":"1f3c3-1f3fe-200d-2640-fe0f","🏃🏿‍♀️":"1f3c3-1f3ff-200d-2640-fe0f","🧖🏻‍♀️":"1f9d6-1f3fb-200d-2640-fe0f","🧖🏼‍♀️":"1f9d6-1f3fc-200d-2640-fe0f","🧖🏽‍♀️":"1f9d6-1f3fd-200d-2640-fe0f","🧖🏾‍♀️":"1f9d6-1f3fe-200d-2640-fe0f","🧖🏿‍♀️":"1f9d6-1f3ff-200d-2640-fe0f","🧖🏻‍♂️":"1f9d6-1f3fb-200d-2642-fe0f","🧖🏼‍♂️":"1f9d6-1f3fc-200d-2642-fe0f","🧖🏽‍♂️":"1f9d6-1f3fd-200d-2642-fe0f","🧖🏾‍♂️":"1f9d6-1f3fe-200d-2642-fe0f","🧖🏿‍♂️":"1f9d6-1f3ff-200d-2642-fe0f","🧗🏻‍♀️":"1f9d7-1f3fb-200d-2640-fe0f","🧗🏼‍♀️":"1f9d7-1f3fc-200d-2640-fe0f","🧗🏽‍♀️":"1f9d7-1f3fd-200d-2640-fe0f","🧗🏾‍♀️":"1f9d7-1f3fe-200d-2640-fe0f","🧗🏿‍♀️":"1f9d7-1f3ff-200d-2640-fe0f","🧗🏻‍♂️":"1f9d7-1f3fb-200d-2642-fe0f","🧗🏼‍♂️":"1f9d7-1f3fc-200d-2642-fe0f","🧗🏽‍♂️":"1f9d7-1f3fd-200d-2642-fe0f","🧗🏾‍♂️":"1f9d7-1f3fe-200d-2642-fe0f","🧗🏿‍♂️":"1f9d7-1f3ff-200d-2642-fe0f","🧘🏻‍♀️":"1f9d8-1f3fb-200d-2640-fe0f","🧘🏼‍♀️":"1f9d8-1f3fc-200d-2640-fe0f","🧘🏽‍♀️":"1f9d8-1f3fd-200d-2640-fe0f","🧘🏾‍♀️":"1f9d8-1f3fe-200d-2640-fe0f","🧘🏿‍♀️":"1f9d8-1f3ff-200d-2640-fe0f","🧘🏻‍♂️":"1f9d8-1f3fb-200d-2642-fe0f","🧘🏼‍♂️":"1f9d8-1f3fc-200d-2642-fe0f","🧘🏽‍♂️":"1f9d8-1f3fd-200d-2642-fe0f","🧘🏾‍♂️":"1f9d8-1f3fe-200d-2642-fe0f","🧘🏿‍♂️":"1f9d8-1f3ff-200d-2642-fe0f","🏌️‍♂️":"1f3cc-fe0f-200d-2642-fe0f","🏌🏻‍♂️":"1f3cc-1f3fb-200d-2642-fe0f","🏌🏼‍♂️":"1f3cc-1f3fc-200d-2642-fe0f","🏌🏽‍♂️":"1f3cc-1f3fd-200d-2642-fe0f","🏌🏾‍♂️":"1f3cc-1f3fe-200d-2642-fe0f","🏌🏿‍♂️":"1f3cc-1f3ff-200d-2642-fe0f","🏌️‍♀️":"1f3cc-fe0f-200d-2640-fe0f","🏌🏻‍♀️":"1f3cc-1f3fb-200d-2640-fe0f","🏌🏼‍♀️":"1f3cc-1f3fc-200d-2640-fe0f","🏌🏽‍♀️":"1f3cc-1f3fd-200d-2640-fe0f","🏌🏾‍♀️":"1f3cc-1f3fe-200d-2640-fe0f","🏌🏿‍♀️":"1f3cc-1f3ff-200d-2640-fe0f","🏄🏻‍♂️":"1f3c4-1f3fb-200d-2642-fe0f","🏄🏼‍♂️":"1f3c4-1f3fc-200d-2642-fe0f","🏄🏽‍♂️":"1f3c4-1f3fd-200d-2642-fe0f","🏄🏾‍♂️":"1f3c4-1f3fe-200d-2642-fe0f","🏄🏿‍♂️":"1f3c4-1f3ff-200d-2642-fe0f","🏄🏻‍♀️":"1f3c4-1f3fb-200d-2640-fe0f","🏄🏼‍♀️":"1f3c4-1f3fc-200d-2640-fe0f","🏄🏽‍♀️":"1f3c4-1f3fd-200d-2640-fe0f","🏄🏾‍♀️":"1f3c4-1f3fe-200d-2640-fe0f","🏄🏿‍♀️":"1f3c4-1f3ff-200d-2640-fe0f","🚣🏻‍♂️":"1f6a3-1f3fb-200d-2642-fe0f","🚣🏼‍♂️":"1f6a3-1f3fc-200d-2642-fe0f","🚣🏽‍♂️":"1f6a3-1f3fd-200d-2642-fe0f","🚣🏾‍♂️":"1f6a3-1f3fe-200d-2642-fe0f","🚣🏿‍♂️":"1f6a3-1f3ff-200d-2642-fe0f","🚣🏻‍♀️":"1f6a3-1f3fb-200d-2640-fe0f","🚣🏼‍♀️":"1f6a3-1f3fc-200d-2640-fe0f","🚣🏽‍♀️":"1f6a3-1f3fd-200d-2640-fe0f","🚣🏾‍♀️":"1f6a3-1f3fe-200d-2640-fe0f","🚣🏿‍♀️":"1f6a3-1f3ff-200d-2640-fe0f","🏊🏻‍♂️":"1f3ca-1f3fb-200d-2642-fe0f","🏊🏼‍♂️":"1f3ca-1f3fc-200d-2642-fe0f","🏊🏽‍♂️":"1f3ca-1f3fd-200d-2642-fe0f","🏊🏾‍♂️":"1f3ca-1f3fe-200d-2642-fe0f","🏊🏿‍♂️":"1f3ca-1f3ff-200d-2642-fe0f","🏊🏻‍♀️":"1f3ca-1f3fb-200d-2640-fe0f","🏊🏼‍♀️":"1f3ca-1f3fc-200d-2640-fe0f","🏊🏽‍♀️":"1f3ca-1f3fd-200d-2640-fe0f","🏊🏾‍♀️":"1f3ca-1f3fe-200d-2640-fe0f","🏊🏿‍♀️":"1f3ca-1f3ff-200d-2640-fe0f","⛹️‍♂️":"26f9-fe0f-200d-2642-fe0f","⛹🏻‍♂️":"26f9-1f3fb-200d-2642-fe0f","⛹🏼‍♂️":"26f9-1f3fc-200d-2642-fe0f","⛹🏽‍♂️":"26f9-1f3fd-200d-2642-fe0f","⛹🏾‍♂️":"26f9-1f3fe-200d-2642-fe0f","⛹🏿‍♂️":"26f9-1f3ff-200d-2642-fe0f","⛹️‍♀️":"26f9-fe0f-200d-2640-fe0f","⛹🏻‍♀️":"26f9-1f3fb-200d-2640-fe0f","⛹🏼‍♀️":"26f9-1f3fc-200d-2640-fe0f","⛹🏽‍♀️":"26f9-1f3fd-200d-2640-fe0f","⛹🏾‍♀️":"26f9-1f3fe-200d-2640-fe0f","⛹🏿‍♀️":"26f9-1f3ff-200d-2640-fe0f","🏋️‍♂️":"1f3cb-fe0f-200d-2642-fe0f","🏋🏻‍♂️":"1f3cb-1f3fb-200d-2642-fe0f","🏋🏼‍♂️":"1f3cb-1f3fc-200d-2642-fe0f","🏋🏽‍♂️":"1f3cb-1f3fd-200d-2642-fe0f","🏋🏾‍♂️":"1f3cb-1f3fe-200d-2642-fe0f","🏋🏿‍♂️":"1f3cb-1f3ff-200d-2642-fe0f","🏋️‍♀️":"1f3cb-fe0f-200d-2640-fe0f","🏋🏻‍♀️":"1f3cb-1f3fb-200d-2640-fe0f","🏋🏼‍♀️":"1f3cb-1f3fc-200d-2640-fe0f","🏋🏽‍♀️":"1f3cb-1f3fd-200d-2640-fe0f","🏋🏾‍♀️":"1f3cb-1f3fe-200d-2640-fe0f","🏋🏿‍♀️":"1f3cb-1f3ff-200d-2640-fe0f","🚴🏻‍♂️":"1f6b4-1f3fb-200d-2642-fe0f","🚴🏼‍♂️":"1f6b4-1f3fc-200d-2642-fe0f","🚴🏽‍♂️":"1f6b4-1f3fd-200d-2642-fe0f","🚴🏾‍♂️":"1f6b4-1f3fe-200d-2642-fe0f","🚴🏿‍♂️":"1f6b4-1f3ff-200d-2642-fe0f","🚴🏻‍♀️":"1f6b4-1f3fb-200d-2640-fe0f","🚴🏼‍♀️":"1f6b4-1f3fc-200d-2640-fe0f","🚴🏽‍♀️":"1f6b4-1f3fd-200d-2640-fe0f","🚴🏾‍♀️":"1f6b4-1f3fe-200d-2640-fe0f","🚴🏿‍♀️":"1f6b4-1f3ff-200d-2640-fe0f","🚵🏻‍♂️":"1f6b5-1f3fb-200d-2642-fe0f","🚵🏼‍♂️":"1f6b5-1f3fc-200d-2642-fe0f","🚵🏽‍♂️":"1f6b5-1f3fd-200d-2642-fe0f","🚵🏾‍♂️":"1f6b5-1f3fe-200d-2642-fe0f","🚵🏿‍♂️":"1f6b5-1f3ff-200d-2642-fe0f","🚵🏻‍♀️":"1f6b5-1f3fb-200d-2640-fe0f","🚵🏼‍♀️":"1f6b5-1f3fc-200d-2640-fe0f","🚵🏽‍♀️":"1f6b5-1f3fd-200d-2640-fe0f","🚵🏾‍♀️":"1f6b5-1f3fe-200d-2640-fe0f","🚵🏿‍♀️":"1f6b5-1f3ff-200d-2640-fe0f","🤸🏻‍♂️":"1f938-1f3fb-200d-2642-fe0f","🤸🏼‍♂️":"1f938-1f3fc-200d-2642-fe0f","🤸🏽‍♂️":"1f938-1f3fd-200d-2642-fe0f","🤸🏾‍♂️":"1f938-1f3fe-200d-2642-fe0f","🤸🏿‍♂️":"1f938-1f3ff-200d-2642-fe0f","🤸🏻‍♀️":"1f938-1f3fb-200d-2640-fe0f","🤸🏼‍♀️":"1f938-1f3fc-200d-2640-fe0f","🤸🏽‍♀️":"1f938-1f3fd-200d-2640-fe0f","🤸🏾‍♀️":"1f938-1f3fe-200d-2640-fe0f","🤸🏿‍♀️":"1f938-1f3ff-200d-2640-fe0f","🤽🏻‍♂️":"1f93d-1f3fb-200d-2642-fe0f","🤽🏼‍♂️":"1f93d-1f3fc-200d-2642-fe0f","🤽🏽‍♂️":"1f93d-1f3fd-200d-2642-fe0f","🤽🏾‍♂️":"1f93d-1f3fe-200d-2642-fe0f","🤽🏿‍♂️":"1f93d-1f3ff-200d-2642-fe0f","🤽🏻‍♀️":"1f93d-1f3fb-200d-2640-fe0f","🤽🏼‍♀️":"1f93d-1f3fc-200d-2640-fe0f","🤽🏽‍♀️":"1f93d-1f3fd-200d-2640-fe0f","🤽🏾‍♀️":"1f93d-1f3fe-200d-2640-fe0f","🤽🏿‍♀️":"1f93d-1f3ff-200d-2640-fe0f","🤾🏻‍♂️":"1f93e-1f3fb-200d-2642-fe0f","🤾🏼‍♂️":"1f93e-1f3fc-200d-2642-fe0f","🤾🏽‍♂️":"1f93e-1f3fd-200d-2642-fe0f","🤾🏾‍♂️":"1f93e-1f3fe-200d-2642-fe0f","🤾🏿‍♂️":"1f93e-1f3ff-200d-2642-fe0f","🤾🏻‍♀️":"1f93e-1f3fb-200d-2640-fe0f","🤾🏼‍♀️":"1f93e-1f3fc-200d-2640-fe0f","🤾🏽‍♀️":"1f93e-1f3fd-200d-2640-fe0f","🤾🏾‍♀️":"1f93e-1f3fe-200d-2640-fe0f","🤾🏿‍♀️":"1f93e-1f3ff-200d-2640-fe0f","🤹🏻‍♂️":"1f939-1f3fb-200d-2642-fe0f","🤹🏼‍♂️":"1f939-1f3fc-200d-2642-fe0f","🤹🏽‍♂️":"1f939-1f3fd-200d-2642-fe0f","🤹🏾‍♂️":"1f939-1f3fe-200d-2642-fe0f","🤹🏿‍♂️":"1f939-1f3ff-200d-2642-fe0f","🤹🏻‍♀️":"1f939-1f3fb-200d-2640-fe0f","🤹🏼‍♀️":"1f939-1f3fc-200d-2640-fe0f","🤹🏽‍♀️":"1f939-1f3fd-200d-2640-fe0f","🤹🏾‍♀️":"1f939-1f3fe-200d-2640-fe0f","🤹🏿‍♀️":"1f939-1f3ff-200d-2640-fe0f","👩‍❤‍👨":"1f469-200d-2764-fe0f-200d-1f468","👨‍❤‍👨":"1f468-200d-2764-fe0f-200d-1f468","👩‍❤‍👩":"1f469-200d-2764-fe0f-200d-1f469","👨‍👩‍👦":"1f468-200d-1f469-200d-1f466","👨‍👩‍👧":"1f468-200d-1f469-200d-1f467","👨‍👨‍👦":"1f468-200d-1f468-200d-1f466","👨‍👨‍👧":"1f468-200d-1f468-200d-1f467","👩‍👩‍👦":"1f469-200d-1f469-200d-1f466","👩‍👩‍👧":"1f469-200d-1f469-200d-1f467","👨‍👦‍👦":"1f468-200d-1f466-200d-1f466","👨‍👧‍👦":"1f468-200d-1f467-200d-1f466","👨‍👧‍👧":"1f468-200d-1f467-200d-1f467","👩‍👦‍👦":"1f469-200d-1f466-200d-1f466","👩‍👧‍👦":"1f469-200d-1f467-200d-1f466","👩‍👧‍👧":"1f469-200d-1f467-200d-1f467","👁️‍🗨️":"1f441-200d-1f5e8","👩‍❤️‍👨":"1f469-200d-2764-fe0f-200d-1f468","👨‍❤️‍👨":"1f468-200d-2764-fe0f-200d-1f468","👩‍❤️‍👩":"1f469-200d-2764-fe0f-200d-1f469","👩‍❤‍💋‍👨":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","👨‍❤‍💋‍👨":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","👩‍❤‍💋‍👩":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469","👨‍👩‍👧‍👦":"1f468-200d-1f469-200d-1f467-200d-1f466","👨‍👩‍👦‍👦":"1f468-200d-1f469-200d-1f466-200d-1f466","👨‍👩‍👧‍👧":"1f468-200d-1f469-200d-1f467-200d-1f467","👨‍👨‍👧‍👦":"1f468-200d-1f468-200d-1f467-200d-1f466","👨‍👨‍👦‍👦":"1f468-200d-1f468-200d-1f466-200d-1f466","👨‍👨‍👧‍👧":"1f468-200d-1f468-200d-1f467-200d-1f467","👩‍👩‍👧‍👦":"1f469-200d-1f469-200d-1f467-200d-1f466","👩‍👩‍👦‍👦":"1f469-200d-1f469-200d-1f466-200d-1f466","👩‍👩‍👧‍👧":"1f469-200d-1f469-200d-1f467-200d-1f467","🏴󠁧󠁢󠁥󠁮󠁧󠁿":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f","🏴󠁧󠁢󠁳󠁣󠁴󠁿":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f","🏴󠁧󠁢󠁷󠁬󠁳󠁿":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f","👩‍❤️‍💋‍👨":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","👨‍❤️‍💋‍👨":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","👩‍❤️‍💋‍👩":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469"}
\ No newline at end of file
diff --git a/app/javascript/mastodon/features/emoji/emoji_mart_search_light.js b/app/javascript/mastodon/features/emoji/emoji_mart_search_light.js
index 36351ec022d0c58a1e4c0c8445317a7ebdea72f5..164fdcc0b8a69f599a63d9128095f9b9c89c095e 100644
--- a/app/javascript/mastodon/features/emoji/emoji_mart_search_light.js
+++ b/app/javascript/mastodon/features/emoji/emoji_mart_search_light.js
@@ -2,7 +2,7 @@
 // https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/emoji-index.js
 
 import data from './emoji_mart_data_light';
-import { getData, getSanitizedData, intersect } from './emoji_utils';
+import { getData, getSanitizedData, uniq, intersect } from './emoji_utils';
 
 let originalPool = {};
 let index = {};
@@ -103,7 +103,7 @@ function search(value, { emojisToShowFilter, maxResults, include, exclude, custo
       }
     }
 
-    allResults = values.map((value) => {
+    const searchValue = (value) => {
       let aPool = pool,
         aIndex = index,
         length = 0;
@@ -150,15 +150,23 @@ function search(value, { emojisToShowFilter, maxResults, include, exclude, custo
       }
 
       return aIndex.results;
-    }).filter(a => a);
+    };
 
-    if (allResults.length > 1) {
-      results = intersect.apply(null, allResults);
-    } else if (allResults.length) {
-      results = allResults[0];
+    if (values.length > 1) {
+      results = searchValue(value);
     } else {
       results = [];
     }
+
+    allResults = values.map(searchValue).filter(a => a);
+
+    if (allResults.length > 1) {
+      allResults = intersect.apply(null, allResults);
+    } else if (allResults.length) {
+      allResults = allResults[0];
+    }
+
+    results = uniq(results.concat(allResults));
   }
 
   if (results) {
diff --git a/app/javascript/mastodon/features/favourited_statuses/index.js b/app/javascript/mastodon/features/favourited_statuses/index.js
index 6f1c863b43c6cbf6b86ae098abb8b9a3708ee1e5..fa9401b90ea16ff523129b50ce998ead6db4b988 100644
--- a/app/javascript/mastodon/features/favourited_statuses/index.js
+++ b/app/javascript/mastodon/features/favourited_statuses/index.js
@@ -7,7 +7,7 @@ import Column from '../ui/components/column';
 import ColumnHeader from '../../components/column_header';
 import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 import StatusList from '../../components/status_list';
-import { defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { debounce } from 'lodash';
 
@@ -21,12 +21,13 @@ const mapStateToProps = state => ({
   hasMore: !!state.getIn(['status_lists', 'favourites', 'next']),
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class Favourites extends ImmutablePureComponent {
+class Favourites extends ImmutablePureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     statusIds: ImmutablePropTypes.list.isRequired,
     intl: PropTypes.object.isRequired,
     columnId: PropTypes.string,
@@ -67,11 +68,13 @@ export default class Favourites extends ImmutablePureComponent {
   }, 300, { leading: true })
 
   render () {
-    const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
+    const { intl, shouldUpdateScroll, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
     const pinned = !!columnId;
 
+    const emptyMessage = <FormattedMessage id='empty_column.favourited_statuses' defaultMessage="You don't have any favourite toots yet. When you favourite one, it will show up here." />;
+
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={intl.formatMessage(messages.heading)}>
         <ColumnHeader
           icon='star'
           title={intl.formatMessage(messages.heading)}
@@ -90,6 +93,8 @@ export default class Favourites extends ImmutablePureComponent {
           hasMore={hasMore}
           isLoading={isLoading}
           onLoadMore={this.handleLoadMore}
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={emptyMessage}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/favourites/index.js b/app/javascript/mastodon/features/favourites/index.js
index 6f113beb431a499e89196649cdcb4321d4a65bce..d1ac229a279148e4a60a1e0fcc978220d92b634f 100644
--- a/app/javascript/mastodon/features/favourites/index.js
+++ b/app/javascript/mastodon/features/favourites/index.js
@@ -1,25 +1,27 @@
 import React from 'react';
 import { connect } from 'react-redux';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import LoadingIndicator from '../../components/loading_indicator';
 import { fetchFavourites } from '../../actions/interactions';
-import { ScrollContainer } from 'react-router-scroll-4';
+import { FormattedMessage } from 'react-intl';
 import AccountContainer from '../../containers/account_container';
 import Column from '../ui/components/column';
 import ColumnBackButton from '../../components/column_back_button';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import ScrollableList from '../../components/scrollable_list';
 
 const mapStateToProps = (state, props) => ({
   accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]),
 });
 
-@connect(mapStateToProps)
-export default class Favourites extends ImmutablePureComponent {
+export default @connect(mapStateToProps)
+class Favourites extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
   };
 
@@ -34,7 +36,7 @@ export default class Favourites extends ImmutablePureComponent {
   }
 
   render () {
-    const { accountIds } = this.props;
+    const { shouldUpdateScroll, accountIds } = this.props;
 
     if (!accountIds) {
       return (
@@ -44,15 +46,21 @@ export default class Favourites extends ImmutablePureComponent {
       );
     }
 
+    const emptyMessage = <FormattedMessage id='empty_column.favourites' defaultMessage='No one has favourited this toot yet. When someone does, they will show up here.' />;
+
     return (
       <Column>
         <ColumnBackButton />
 
-        <ScrollContainer scrollKey='favourites'>
-          <div className='scrollable'>
-            {accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
-          </div>
-        </ScrollContainer>
+        <ScrollableList
+          scrollKey='favourites'
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={emptyMessage}
+        >
+          {accountIds.map(id =>
+            <AccountContainer key={id} id={id} withNote={false} />
+          )}
+        </ScrollableList>
       </Column>
     );
   }
diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
index 4fc5638d95780b793d8c341ed306abfa074e204c..a3b524db1d4398dbc3a394d354568185dc2c2b98 100644
--- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
+++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
@@ -13,8 +13,8 @@ const messages = defineMessages({
   reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
 });
 
-@injectIntl
-export default class AccountAuthorize extends ImmutablePureComponent {
+export default @injectIntl
+class AccountAuthorize extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
diff --git a/app/javascript/mastodon/features/follow_requests/index.js b/app/javascript/mastodon/features/follow_requests/index.js
index eae821f9250569d0433f435089ea41d384a9b82d..56ae8764b42dd6c7f56ae24a4136da505bc6f442 100644
--- a/app/javascript/mastodon/features/follow_requests/index.js
+++ b/app/javascript/mastodon/features/follow_requests/index.js
@@ -1,15 +1,16 @@
 import React from 'react';
 import { connect } from 'react-redux';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import { debounce } from 'lodash';
 import LoadingIndicator from '../../components/loading_indicator';
-import { ScrollContainer } from 'react-router-scroll-4';
 import Column from '../ui/components/column';
 import ColumnBackButtonSlim from '../../components/column_back_button_slim';
 import AccountAuthorizeContainer from './containers/account_authorize_container';
 import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts';
-import { defineMessages, injectIntl } from 'react-intl';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import ScrollableList from '../../components/scrollable_list';
 
 const messages = defineMessages({
   heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
@@ -19,13 +20,14 @@ const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class FollowRequests extends ImmutablePureComponent {
+class FollowRequests extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
     intl: PropTypes.object.isRequired,
   };
@@ -34,16 +36,12 @@ export default class FollowRequests extends ImmutablePureComponent {
     this.props.dispatch(fetchFollowRequests());
   }
 
-  handleScroll = (e) => {
-    const { scrollTop, scrollHeight, clientHeight } = e.target;
-
-    if (scrollTop === scrollHeight - clientHeight) {
-      this.props.dispatch(expandFollowRequests());
-    }
-  }
+  handleLoadMore = debounce(() => {
+    this.props.dispatch(expandFollowRequests());
+  }, 300, { leading: true });
 
   render () {
-    const { intl, accountIds } = this.props;
+    const { intl, shouldUpdateScroll, accountIds } = this.props;
 
     if (!accountIds) {
       return (
@@ -53,17 +51,21 @@ export default 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)}>
         <ColumnBackButtonSlim />
-
-        <ScrollContainer scrollKey='follow_requests'>
-          <div className='scrollable' onScroll={this.handleScroll}>
-            {accountIds.map(id =>
-              <AccountAuthorizeContainer key={id} id={id} />
-            )}
-          </div>
-        </ScrollContainer>
+        <ScrollableList
+          scrollKey='follow_requests'
+          onLoadMore={this.handleLoadMore}
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={emptyMessage}
+        >
+          {accountIds.map(id =>
+            <AccountAuthorizeContainer key={id} id={id} />
+          )}
+        </ScrollableList>
       </Column>
     );
   }
diff --git a/app/javascript/mastodon/features/followers/index.js b/app/javascript/mastodon/features/followers/index.js
index 919a89332b12fe9ac3a2131d90fd9f19e06e04fc..ce56f270ca361836efaf76bcb30120f6d835de06 100644
--- a/app/javascript/mastodon/features/followers/index.js
+++ b/app/javascript/mastodon/features/followers/index.js
@@ -1,32 +1,34 @@
 import React from 'react';
 import { connect } from 'react-redux';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import { debounce } from 'lodash';
 import LoadingIndicator from '../../components/loading_indicator';
 import {
   fetchAccount,
   fetchFollowers,
   expandFollowers,
 } from '../../actions/accounts';
-import { ScrollContainer } from 'react-router-scroll-4';
+import { FormattedMessage } from 'react-intl';
 import AccountContainer from '../../containers/account_container';
 import Column from '../ui/components/column';
 import HeaderContainer from '../account_timeline/containers/header_container';
-import LoadMore from '../../components/load_more';
 import ColumnBackButton from '../../components/column_back_button';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import ScrollableList from '../../components/scrollable_list';
 
 const mapStateToProps = (state, props) => ({
   accountIds: state.getIn(['user_lists', 'followers', props.params.accountId, 'items']),
   hasMore: !!state.getIn(['user_lists', 'followers', props.params.accountId, 'next']),
 });
 
-@connect(mapStateToProps)
-export default class Followers extends ImmutablePureComponent {
+export default @connect(mapStateToProps)
+class Followers extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
     hasMore: PropTypes.bool,
   };
@@ -43,23 +45,12 @@ export default class Followers extends ImmutablePureComponent {
     }
   }
 
-  handleScroll = (e) => {
-    const { scrollTop, scrollHeight, clientHeight } = e.target;
-
-    if (scrollTop === scrollHeight - clientHeight && this.props.hasMore) {
-      this.props.dispatch(expandFollowers(this.props.params.accountId));
-    }
-  }
-
-  handleLoadMore = (e) => {
-    e.preventDefault();
+  handleLoadMore = debounce(() => {
     this.props.dispatch(expandFollowers(this.props.params.accountId));
-  }
+  }, 300, { leading: true });
 
   render () {
-    const { accountIds, hasMore } = this.props;
-
-    let loadMore = null;
+    const { shouldUpdateScroll, accountIds, hasMore } = this.props;
 
     if (!accountIds) {
       return (
@@ -69,23 +60,25 @@ export default class Followers extends ImmutablePureComponent {
       );
     }
 
-    if (hasMore) {
-      loadMore = <LoadMore onClick={this.handleLoadMore} />;
-    }
+    const emptyMessage = <FormattedMessage id='account.followers.empty' defaultMessage='No one follows this user yet.' />;
 
     return (
       <Column>
         <ColumnBackButton />
 
-        <ScrollContainer scrollKey='followers'>
-          <div className='scrollable' onScroll={this.handleScroll}>
-            <div className='followers'>
-              <HeaderContainer accountId={this.props.params.accountId} hideTabs />
-              {accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
-              {loadMore}
-            </div>
-          </div>
-        </ScrollContainer>
+        <ScrollableList
+          scrollKey='followers'
+          hasMore={hasMore}
+          onLoadMore={this.handleLoadMore}
+          shouldUpdateScroll={shouldUpdateScroll}
+          prepend={<HeaderContainer accountId={this.props.params.accountId} hideTabs />}
+          alwaysPrepend
+          emptyMessage={emptyMessage}
+        >
+          {accountIds.map(id =>
+            <AccountContainer key={id} id={id} withNote={false} />
+          )}
+        </ScrollableList>
       </Column>
     );
   }
diff --git a/app/javascript/mastodon/features/following/index.js b/app/javascript/mastodon/features/following/index.js
index 5719259d11114e6ef089e75a0d66cb9e93173e77..bda0438a0a582ac137329b6394ad2fa0d518498f 100644
--- a/app/javascript/mastodon/features/following/index.js
+++ b/app/javascript/mastodon/features/following/index.js
@@ -1,32 +1,34 @@
 import React from 'react';
 import { connect } from 'react-redux';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import { debounce } from 'lodash';
 import LoadingIndicator from '../../components/loading_indicator';
 import {
   fetchAccount,
   fetchFollowing,
   expandFollowing,
 } from '../../actions/accounts';
-import { ScrollContainer } from 'react-router-scroll-4';
+import { FormattedMessage } from 'react-intl';
 import AccountContainer from '../../containers/account_container';
 import Column from '../ui/components/column';
 import HeaderContainer from '../account_timeline/containers/header_container';
-import LoadMore from '../../components/load_more';
 import ColumnBackButton from '../../components/column_back_button';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import ScrollableList from '../../components/scrollable_list';
 
 const mapStateToProps = (state, props) => ({
   accountIds: state.getIn(['user_lists', 'following', props.params.accountId, 'items']),
   hasMore: !!state.getIn(['user_lists', 'following', props.params.accountId, 'next']),
 });
 
-@connect(mapStateToProps)
-export default class Following extends ImmutablePureComponent {
+export default @connect(mapStateToProps)
+class Following extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
     hasMore: PropTypes.bool,
   };
@@ -43,23 +45,12 @@ export default class Following extends ImmutablePureComponent {
     }
   }
 
-  handleScroll = (e) => {
-    const { scrollTop, scrollHeight, clientHeight } = e.target;
-
-    if (scrollTop === scrollHeight - clientHeight && this.props.hasMore) {
-      this.props.dispatch(expandFollowing(this.props.params.accountId));
-    }
-  }
-
-  handleLoadMore = (e) => {
-    e.preventDefault();
+  handleLoadMore = debounce(() => {
     this.props.dispatch(expandFollowing(this.props.params.accountId));
-  }
+  }, 300, { leading: true });
 
   render () {
-    const { accountIds, hasMore } = this.props;
-
-    let loadMore = null;
+    const { shouldUpdateScroll, accountIds, hasMore } = this.props;
 
     if (!accountIds) {
       return (
@@ -69,23 +60,25 @@ export default class Following extends ImmutablePureComponent {
       );
     }
 
-    if (hasMore) {
-      loadMore = <LoadMore onClick={this.handleLoadMore} />;
-    }
+    const emptyMessage = <FormattedMessage id='account.follows.empty' defaultMessage="This user doesn't follow anyone yet." />;
 
     return (
       <Column>
         <ColumnBackButton />
 
-        <ScrollContainer scrollKey='following'>
-          <div className='scrollable' onScroll={this.handleScroll}>
-            <div className='following'>
-              <HeaderContainer accountId={this.props.params.accountId} hideTabs />
-              {accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
-              {loadMore}
-            </div>
-          </div>
-        </ScrollContainer>
+        <ScrollableList
+          scrollKey='following'
+          hasMore={hasMore}
+          onLoadMore={this.handleLoadMore}
+          shouldUpdateScroll={shouldUpdateScroll}
+          prepend={<HeaderContainer accountId={this.props.params.accountId} hideTabs />}
+          alwaysPrepend
+          emptyMessage={emptyMessage}
+        >
+          {accountIds.map(id =>
+            <AccountContainer key={id} id={id} withNote={false} />
+          )}
+        </ScrollableList>
       </Column>
     );
   }
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js
index 99642c911578b63a197c934efb93d3aca61f4cbf..709a3aa96dfd3a0ad6a0f32e4421b8fa69e8a604 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.js
@@ -7,7 +7,7 @@ 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 } from '../../initial_state';
+import { me, invitesEnabled, version, profile_directory } from '../../initial_state';
 import { fetchFollowRequests } from '../../actions/accounts';
 import { List as ImmutableList } from 'immutable';
 import { Link } from 'react-router-dom';
@@ -31,6 +31,8 @@ const messages = defineMessages({
   discover: { id: 'navigation_bar.discover', defaultMessage: 'Discover' },
   personal: { id: 'navigation_bar.personal', defaultMessage: 'Personal' },
   security: { id: 'navigation_bar.security', defaultMessage: 'Security' },
+  menu: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
+  profile_directory: { id: 'getting_started.directory', defaultMessage: 'Profile directory' },
 });
 
 const mapStateToProps = state => ({
@@ -52,9 +54,9 @@ const badgeDisplay = (number, limit) => {
   }
 };
 
-@connect(mapStateToProps, mapDispatchToProps)
+export default @connect(mapStateToProps, mapDispatchToProps)
 @injectIntl
-export default class GettingStarted extends ImmutablePureComponent {
+class GettingStarted extends ImmutablePureComponent {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
@@ -86,10 +88,29 @@ export default class GettingStarted extends ImmutablePureComponent {
         <ColumnSubheading key={i++} text={intl.formatMessage(messages.discover)} />,
         <ColumnLink key={i++} icon='users' text={intl.formatMessage(messages.community_timeline)} to='/timelines/public/local' />,
         <ColumnLink key={i++} icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' />,
+      );
+
+      height += 34 + 48*2;
+
+      if (profile_directory) {
+        navItems.push(
+          <ColumnLink key={i++} icon='address-book' text={intl.formatMessage(messages.profile_directory)} href='/explore' />
+        );
+
+        height += 48;
+      }
+
+      navItems.push(
         <ColumnSubheading key={i++} text={intl.formatMessage(messages.personal)} />
       );
 
-      height += 34*2 + 48*2;
+      height += 34;
+    } else if (profile_directory) {
+      navItems.push(
+        <ColumnLink key={i++} icon='address-book' text={intl.formatMessage(messages.profile_directory)} href='/explore' />
+      );
+
+      height += 48;
     }
 
     navItems.push(
@@ -115,7 +136,7 @@ export default class GettingStarted extends ImmutablePureComponent {
     }
 
     return (
-      <Column>
+      <Column label={intl.formatMessage(messages.menu)}>
         {multiColumn && <div className='column-header__wrapper'>
           <h1 className='column-header'>
             <button>
@@ -125,33 +146,35 @@ export default class GettingStarted extends ImmutablePureComponent {
           </h1>
         </div>}
 
-        <div className='getting-started__wrapper' style={{ height }}>
-          {!multiColumn && <NavigationBar account={myAccount} />}
-          {navItems}
-        </div>
-
-        {!multiColumn && <div className='flex-spacer' />}
-
-        <div className='getting-started getting-started__footer'>
-          <ul>
-            <li><a href='https://bridge.joinmastodon.org/' target='_blank'><FormattedMessage id='getting_started.find_friends' defaultMessage='Find friends from Twitter' /></a> · </li>
-            {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='/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://github.com/tootsuite/documentation#documentation' 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: <a href='https://github.com/tootsuite/mastodon' rel='noopener' target='_blank'>tootsuite/mastodon</a> }}
-            />
-          </p>
+        <div className='getting-started'>
+          <div className='getting-started__wrapper' style={{ height }}>
+            {!multiColumn && <NavigationBar account={myAccount} />}
+            {navItems}
+          </div>
+
+          {!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>
         </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
new file mode 100644
index 0000000000000000000000000000000000000000..9c9f62d8211ebcbf0f2a31551e3b0335be732e97
--- /dev/null
+++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
@@ -0,0 +1,102 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { injectIntl, FormattedMessage } from 'react-intl';
+import Toggle from 'react-toggle';
+import AsyncSelect from 'react-select/lib/Async';
+
+export default @injectIntl
+class ColumnSettings extends React.PureComponent {
+
+  static propTypes = {
+    settings: ImmutablePropTypes.map.isRequired,
+    onChange: PropTypes.func.isRequired,
+    onLoad: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
+  };
+
+  state = {
+    open: this.hasTags(),
+  };
+
+  hasTags () {
+    return ['all', 'any', 'none'].map(mode => this.tags(mode).length > 0).includes(true);
+  }
+
+  tags (mode) {
+    let tags = this.props.settings.getIn(['tags', mode]) || [];
+    if (tags.toJSON) {
+      return tags.toJSON();
+    } else {
+      return tags;
+    }
+  };
+
+  onSelect = (mode) => {
+    return (value) => {
+      this.props.onChange(['tags', mode], value);
+    };
+  };
+
+  onToggle = () => {
+    if (this.state.open && this.hasTags()) {
+      this.props.onChange('tags', {});
+    }
+    this.setState({ open: !this.state.open });
+  };
+
+  modeSelect (mode) {
+    return (
+      <div className='column-settings__section'>
+        {this.modeLabel(mode)}
+        <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'
+          name='tags'
+        />
+      </div>
+    );
+  }
+
+  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' />;
+    }
+    return '';
+  };
+
+  render () {
+    return (
+      <div>
+        <div className='column-settings__row'>
+          <div className='setting-toggle'>
+            <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 &&
+          <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/containers/column_settings_container.js b/app/javascript/mastodon/features/hashtag_timeline/containers/column_settings_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..c5098052ce23f1232a35947f5a41c70933e42ef0
--- /dev/null
+++ b/app/javascript/mastodon/features/hashtag_timeline/containers/column_settings_container.js
@@ -0,0 +1,31 @@
+import { connect } from 'react-redux';
+import ColumnSettings from '../components/column_settings';
+import { changeColumnParams } from '../../../actions/columns';
+import api from '../../../api';
+
+const mapStateToProps = (state, { columnId }) => {
+  const columns = state.getIn(['settings', 'columns']);
+  const index   = columns.findIndex(c => c.get('uuid') === columnId);
+
+  if (!(columnId && index >= 0)) {
+    return {};
+  }
+
+  return { settings: columns.get(index).get('params') };
+};
+
+const mapDispatchToProps = (dispatch, { columnId }) => ({
+  onChange (key, value) {
+    dispatch(changeColumnParams(columnId, key, value));
+  },
+
+  onLoad (value) {
+    return api().get('/api/v2/search', { params: { q: value } }).then(response => {
+      return (response.data.hashtags || []).map((tag) => {
+        return { value: tag.name, label: `#${tag.name}` };
+      });
+    });
+  },
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings);
diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.js b/app/javascript/mastodon/features/hashtag_timeline/index.js
index 374615ac7fd3381d44b8581b42c59ae193358e9f..c2e026d13611d97dca0fcf7d0bf24abb7fa1526c 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/index.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/index.js
@@ -4,22 +4,27 @@ import PropTypes from 'prop-types';
 import StatusListContainer from '../ui/containers/status_list_container';
 import Column from '../../components/column';
 import ColumnHeader from '../../components/column_header';
-import { expandHashtagTimeline } from '../../actions/timelines';
+import ColumnSettingsContainer from './containers/column_settings_container';
+import { expandHashtagTimeline, clearTimeline } from '../../actions/timelines';
 import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 import { FormattedMessage } from 'react-intl';
 import { connectHashtagStream } from '../../actions/streaming';
+import { isEqual } from 'lodash';
 
 const mapStateToProps = (state, props) => ({
   hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}`, 'unread']) > 0,
 });
 
-@connect(mapStateToProps)
-export default class HashtagTimeline extends React.PureComponent {
+export default @connect(mapStateToProps)
+class HashtagTimeline extends React.PureComponent {
+
+  disconnects = [];
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     columnId: PropTypes.string,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     hasUnread: PropTypes.bool,
     multiColumn: PropTypes.bool,
   };
@@ -34,6 +39,30 @@ export default 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}' />);
+    }
+    if (this.additionalFor('all')) {
+      title.push(' ', <FormattedMessage 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}' />);
+    }
+    return title;
+  }
+
+  additionalFor = (mode) => {
+    const { tags } = this.props.params;
+
+    if (tags && (tags[mode] || []).length > 0) {
+      return tags[mode].map(tag => tag.value).join('/');
+    } else {
+      return '';
+    }
+  }
+
   handleMove = (dir) => {
     const { columnId, dispatch } = this.props;
     dispatch(moveColumn(columnId, dir));
@@ -43,30 +72,40 @@ export default class HashtagTimeline extends React.PureComponent {
     this.column.scrollTop();
   }
 
-  _subscribe (dispatch, id) {
-    this.disconnect = dispatch(connectHashtagStream(id));
+  _subscribe (dispatch, id, tags = {}) {
+    let any  = (tags.any || []).map(tag => tag.value);
+    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) => {
+        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;
+      })));
+    });
   }
 
   _unsubscribe () {
-    if (this.disconnect) {
-      this.disconnect();
-      this.disconnect = null;
-    }
+    this.disconnects.map(disconnect => disconnect());
+    this.disconnects = [];
   }
 
   componentDidMount () {
     const { dispatch } = this.props;
-    const { id } = this.props.params;
+    const { id, tags } = this.props.params;
 
-    dispatch(expandHashtagTimeline(id));
-    this._subscribe(dispatch, id);
+    dispatch(expandHashtagTimeline(id, { tags }));
   }
 
   componentWillReceiveProps (nextProps) {
-    if (nextProps.params.id !== this.props.params.id) {
-      this.props.dispatch(expandHashtagTimeline(nextProps.params.id));
+    const { dispatch, params } = this.props;
+    const { id, tags } = nextProps.params;
+    if (id !== params.id || !isEqual(tags, params.tags)) {
       this._unsubscribe();
-      this._subscribe(this.props.dispatch, nextProps.params.id);
+      this._subscribe(dispatch, id, tags);
+      this.props.dispatch(clearTimeline(`hashtag:${id}`));
+      this.props.dispatch(expandHashtagTimeline(id, { tags }));
     }
   }
 
@@ -79,27 +118,30 @@ export default class HashtagTimeline extends React.PureComponent {
   }
 
   handleLoadMore = maxId => {
-    this.props.dispatch(expandHashtagTimeline(this.props.params.id, { maxId }));
+    const { id, tags } = this.props.params;
+    this.props.dispatch(expandHashtagTimeline(id, { maxId, tags }));
   }
 
   render () {
-    const { hasUnread, columnId, multiColumn } = this.props;
+    const { shouldUpdateScroll, hasUnread, columnId, multiColumn } = this.props;
     const { id } = this.props.params;
     const pinned = !!columnId;
 
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={`#${id}`}>
         <ColumnHeader
           icon='hashtag'
           active={hasUnread}
-          title={id}
+          title={this.title()}
           onPin={this.handlePin}
           onMove={this.handleMove}
           onClick={this.handleHeaderClick}
           pinned={pinned}
           multiColumn={multiColumn}
           showBackButton
-        />
+        >
+          {columnId && <ColumnSettingsContainer columnId={columnId} />}
+        </ColumnHeader>
 
         <StatusListContainer
           trackScroll={!pinned}
@@ -107,6 +149,7 @@ export default class HashtagTimeline extends React.PureComponent {
           timelineId={`hashtag:${id}`}
           onLoadMore={this.handleLoadMore}
           emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />}
+          shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/home_timeline/components/column_settings.js b/app/javascript/mastodon/features/home_timeline/components/column_settings.js
index 932ac2049816e9702416cad6e902ced731c2e6c3..455e218817cfe717b0b484a980d405300fc05ab0 100644
--- a/app/javascript/mastodon/features/home_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/home_timeline/components/column_settings.js
@@ -4,8 +4,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import { injectIntl, FormattedMessage } from 'react-intl';
 import SettingToggle from '../../notifications/components/setting_toggle';
 
-@injectIntl
-export default class ColumnSettings extends React.PureComponent {
+export default @injectIntl
+class ColumnSettings extends React.PureComponent {
 
   static propTypes = {
     settings: ImmutablePropTypes.map.isRequired,
diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js
index db6bbdec13416788ec6eadeca4a6e33fe2be7787..3ffa7a681526c40f7474d1dccda53d7f5f37faa0 100644
--- a/app/javascript/mastodon/features/home_timeline/index.js
+++ b/app/javascript/mastodon/features/home_timeline/index.js
@@ -19,12 +19,13 @@ const mapStateToProps = state => ({
   isPartial: state.getIn(['timelines', 'home', 'items', 0], null) === null,
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class HomeTimeline extends React.PureComponent {
+class HomeTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     intl: PropTypes.object.isRequired,
     hasUnread: PropTypes.bool,
     isPartial: PropTypes.bool,
@@ -93,11 +94,11 @@ export default class HomeTimeline extends React.PureComponent {
   }
 
   render () {
-    const { intl, hasUnread, columnId, multiColumn } = this.props;
+    const { intl, shouldUpdateScroll, hasUnread, columnId, multiColumn } = this.props;
     const pinned = !!columnId;
 
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
         <ColumnHeader
           icon='home'
           active={hasUnread}
@@ -117,6 +118,7 @@ export default class HomeTimeline extends React.PureComponent {
           onLoadMore={this.handleLoadMore}
           timelineId='home'
           emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} or use search to get started and meet other users.' values={{ public: <Link to='/timelines/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />}
+          shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/introduction/index.js b/app/javascript/mastodon/features/introduction/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..e712b2f7d4ea3b8c960274e688c96811a08e5517
--- /dev/null
+++ b/app/javascript/mastodon/features/introduction/index.js
@@ -0,0 +1,196 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ReactSwipeableViews from 'react-swipeable-views';
+import classNames from 'classnames';
+import { connect } from 'react-redux';
+import { FormattedMessage } from 'react-intl';
+import { closeOnboarding } from '../../actions/onboarding';
+import screenHello from '../../../images/screen_hello.svg';
+import screenFederation from '../../../images/screen_federation.svg';
+import screenInteractions from '../../../images/screen_interactions.svg';
+import logoTransparent from '../../../images/logo_transparent.svg';
+
+const FrameWelcome = ({ domain, onNext }) => (
+  <div className='introduction__frame'>
+    <div className='introduction__illustration' style={{ background: `url(${logoTransparent}) no-repeat center center / auto 80%` }}>
+      <img src={screenHello} alt='' />
+    </div>
+
+    <div className='introduction__text introduction__text--centered'>
+      <h3><FormattedMessage id='introduction.welcome.headline' defaultMessage='First steps' /></h3>
+      <p><FormattedMessage id='introduction.welcome.text' defaultMessage="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." values={{ domain: <code>{domain}</code> }} /></p>
+    </div>
+
+    <div className='introduction__action'>
+      <button className='button' onClick={onNext}><FormattedMessage id='introduction.welcome.action' defaultMessage="Let's go!" /></button>
+    </div>
+  </div>
+);
+
+FrameWelcome.propTypes = {
+  domain: PropTypes.string.isRequired,
+  onNext: PropTypes.func.isRequired,
+};
+
+const FrameFederation = ({ onNext }) => (
+  <div className='introduction__frame'>
+    <div className='introduction__illustration'>
+      <img src={screenFederation} alt='' />
+    </div>
+
+    <div className='introduction__text introduction__text--columnized'>
+      <div>
+        <h3><FormattedMessage id='introduction.federation.home.headline' defaultMessage='Home' /></h3>
+        <p><FormattedMessage id='introduction.federation.home.text' defaultMessage='Posts from people you follow will appear in your home feed. You can follow anyone on any server!' /></p>
+      </div>
+
+      <div>
+        <h3><FormattedMessage id='introduction.federation.local.headline' defaultMessage='Local' /></h3>
+        <p><FormattedMessage id='introduction.federation.local.text' defaultMessage='Public posts from people on the same server as you will appear in the local timeline.' /></p>
+      </div>
+
+      <div>
+        <h3><FormattedMessage id='introduction.federation.federated.headline' defaultMessage='Federated' /></h3>
+        <p><FormattedMessage id='introduction.federation.federated.text' defaultMessage='Public posts from other servers of the fediverse will appear in the federated timeline.' /></p>
+      </div>
+    </div>
+
+    <div className='introduction__action'>
+      <button className='button' onClick={onNext}><FormattedMessage id='introduction.federation.action' defaultMessage='Next' /></button>
+    </div>
+  </div>
+);
+
+FrameFederation.propTypes = {
+  onNext: PropTypes.func.isRequired,
+};
+
+const FrameInteractions = ({ onNext }) => (
+  <div className='introduction__frame'>
+    <div className='introduction__illustration'>
+      <img src={screenInteractions} alt='' />
+    </div>
+
+    <div className='introduction__text introduction__text--columnized'>
+      <div>
+        <h3><FormattedMessage id='introduction.interactions.reply.headline' defaultMessage='Reply' /></h3>
+        <p><FormattedMessage id='introduction.interactions.reply.text' defaultMessage="You can reply to other people's and your own toots, which will chain them together in a conversation." /></p>
+      </div>
+
+      <div>
+        <h3><FormattedMessage id='introduction.interactions.reblog.headline' defaultMessage='Boost' /></h3>
+        <p><FormattedMessage id='introduction.interactions.reblog.text' defaultMessage="You can share other people's toots with your followers by boosting them." /></p>
+      </div>
+
+      <div>
+        <h3><FormattedMessage id='introduction.interactions.favourite.headline' defaultMessage='Favourite' /></h3>
+        <p><FormattedMessage id='introduction.interactions.favourite.text' defaultMessage='You can save a toot for later, and let the author know that you liked it, by favouriting it.' /></p>
+      </div>
+    </div>
+
+    <div className='introduction__action'>
+      <button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish tutorial!' /></button>
+    </div>
+  </div>
+);
+
+FrameInteractions.propTypes = {
+  onNext: PropTypes.func.isRequired,
+};
+
+export default @connect(state => ({ domain: state.getIn(['meta', 'domain']) }))
+class Introduction extends React.PureComponent {
+
+  static propTypes = {
+    domain: PropTypes.string.isRequired,
+    dispatch: PropTypes.func.isRequired,
+  };
+
+  state = {
+    currentIndex: 0,
+  };
+
+  componentWillMount () {
+    this.pages = [
+      <FrameWelcome domain={this.props.domain} onNext={this.handleNext} />,
+      <FrameFederation onNext={this.handleNext} />,
+      <FrameInteractions onNext={this.handleFinish} />,
+    ];
+  }
+
+  componentDidMount() {
+    window.addEventListener('keyup', this.handleKeyUp);
+  }
+
+  componentWillUnmount() {
+    window.addEventListener('keyup', this.handleKeyUp);
+  }
+
+  handleDot = (e) => {
+    const i = Number(e.currentTarget.getAttribute('data-index'));
+    e.preventDefault();
+    this.setState({ currentIndex: i });
+  }
+
+  handlePrev = () => {
+    this.setState(({ currentIndex }) => ({
+      currentIndex: Math.max(0, currentIndex - 1),
+    }));
+  }
+
+  handleNext = () => {
+    const { pages } = this;
+
+    this.setState(({ currentIndex }) => ({
+      currentIndex: Math.min(currentIndex + 1, pages.length - 1),
+    }));
+  }
+
+  handleSwipe = (index) => {
+    this.setState({ currentIndex: index });
+  }
+
+  handleFinish = () => {
+    this.props.dispatch(closeOnboarding());
+  }
+
+  handleKeyUp = ({ key }) => {
+    switch (key) {
+    case 'ArrowLeft':
+      this.handlePrev();
+      break;
+    case 'ArrowRight':
+      this.handleNext();
+      break;
+    }
+  }
+
+  render () {
+    const { currentIndex } = this.state;
+    const { pages } = this;
+
+    return (
+      <div className='introduction'>
+        <ReactSwipeableViews index={currentIndex} onChangeIndex={this.handleSwipe} className='introduction__pager'>
+          {pages.map((page, i) => (
+            <div key={i} className={classNames('introduction__frame-wrapper', { 'active': i === currentIndex })}>{page}</div>
+          ))}
+        </ReactSwipeableViews>
+
+        <div className='introduction__dots'>
+          {pages.map((_, i) => (
+            <div
+              key={`dot-${i}`}
+              role='button'
+              tabIndex='0'
+              data-index={i}
+              onClick={this.handleDot}
+              className={classNames('introduction__dot', { active: i === currentIndex })}
+            />
+          ))}
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/keyboard_shortcuts/index.js b/app/javascript/mastodon/features/keyboard_shortcuts/index.js
index 5ae7b34a2e6962e052a09590d1580084f1b0ad4e..ab1ac511e0397502290ffc9c5738da16de8de7d8 100644
--- a/app/javascript/mastodon/features/keyboard_shortcuts/index.js
+++ b/app/javascript/mastodon/features/keyboard_shortcuts/index.js
@@ -9,8 +9,8 @@ const messages = defineMessages({
   heading: { id: 'keyboard_shortcuts.heading', defaultMessage: 'Keyboard Shortcuts' },
 });
 
-@injectIntl
-export default class KeyboardShortcuts extends ImmutablePureComponent {
+export default @injectIntl
+class KeyboardShortcuts extends ImmutablePureComponent {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
@@ -40,6 +40,10 @@ export default class KeyboardShortcuts extends ImmutablePureComponent {
                 <td><kbd>m</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.mention' defaultMessage='to mention author' /></td>
               </tr>
+              <tr>
+                <td><kbd>p</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.profile' defaultMessage="to open author's profile" /></td>
+              </tr>
               <tr>
                 <td><kbd>f</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.favourite' defaultMessage='to favourite' /></td>
@@ -49,7 +53,7 @@ export default class KeyboardShortcuts extends ImmutablePureComponent {
                 <td><FormattedMessage id='keyboard_shortcuts.boost' defaultMessage='to boost' /></td>
               </tr>
               <tr>
-                <td><kbd>enter</kbd></td>
+                <td><kbd>enter</kbd>, <kbd>o</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.enter' defaultMessage='to open status' /></td>
               </tr>
               <tr>
@@ -57,11 +61,11 @@ export default class KeyboardShortcuts extends ImmutablePureComponent {
                 <td><FormattedMessage id='keyboard_shortcuts.toggle_hidden' defaultMessage='to show/hide text behind CW' /></td>
               </tr>
               <tr>
-                <td><kbd>up</kbd></td>
+                <td><kbd>up</kbd>, <kbd>k</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.up' defaultMessage='to move up in the list' /></td>
               </tr>
               <tr>
-                <td><kbd>down</kbd></td>
+                <td><kbd>down</kbd>, <kbd>j</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.down' defaultMessage='to move down in the list' /></td>
               </tr>
               <tr>
@@ -88,6 +92,54 @@ export default class KeyboardShortcuts extends ImmutablePureComponent {
                 <td><kbd>esc</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.unfocus' defaultMessage='to un-focus compose textarea/search' /></td>
               </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>h</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.home' defaultMessage='to open home timeline' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>n</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.notifications' defaultMessage='to open notifications column' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>l</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.local' defaultMessage='to open local timeline' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>t</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.federated' defaultMessage='to open federated timeline' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>d</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.direct' defaultMessage='to open direct messages column' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>s</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.start' defaultMessage='to open "get started" column' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>f</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.favourites' defaultMessage='to open favourites list' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>p</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.pinned' defaultMessage='to open pinned toots list' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>u</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.my_profile' defaultMessage='to open your profile' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>b</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.blocked' defaultMessage='to open blocked users list' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>m</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.muted' defaultMessage='to open muted users list' /></td>
+              </tr>
+              <tr>
+                <td><kbd>g</kbd>+<kbd>r</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.requests' defaultMessage='to open follow requests list' /></td>
+              </tr>
               <tr>
                 <td><kbd>?</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.legend' defaultMessage='to display this legend' /></td>
diff --git a/app/javascript/mastodon/features/list_adder/components/account.js b/app/javascript/mastodon/features/list_adder/components/account.js
new file mode 100644
index 0000000000000000000000000000000000000000..1369aac0742c437a48cc2f2bf69b0d2bc5d38c13
--- /dev/null
+++ b/app/javascript/mastodon/features/list_adder/components/account.js
@@ -0,0 +1,43 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { makeGetAccount } from '../../../selectors';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import Avatar from '../../../components/avatar';
+import DisplayName from '../../../components/display_name';
+import { injectIntl } from 'react-intl';
+
+const makeMapStateToProps = () => {
+  const getAccount = makeGetAccount();
+
+  const mapStateToProps = (state, { accountId }) => ({
+    account: getAccount(state, accountId),
+  });
+
+  return mapStateToProps;
+};
+
+
+export default @connect(makeMapStateToProps)
+@injectIntl
+class Account extends ImmutablePureComponent {
+
+  static propTypes = {
+    account: ImmutablePropTypes.map.isRequired,
+  };
+
+  render () {
+    const { account } = this.props;
+    return (
+      <div className='account'>
+        <div className='account__wrapper'>
+          <div className='account__display-name'>
+            <div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
+            <DisplayName account={account} />
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/list_adder/components/list.js b/app/javascript/mastodon/features/list_adder/components/list.js
new file mode 100644
index 0000000000000000000000000000000000000000..cb8eb7d7a91a85657fc1d91c27c6b9867832bce9
--- /dev/null
+++ b/app/javascript/mastodon/features/list_adder/components/list.js
@@ -0,0 +1,68 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import IconButton from '../../../components/icon_button';
+import { defineMessages, injectIntl } from 'react-intl';
+import { removeFromListAdder, addToListAdder } from '../../../actions/lists';
+
+const messages = defineMessages({
+  remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' },
+  add: { id: 'lists.account.add', defaultMessage: 'Add to list' },
+});
+
+const MapStateToProps = (state, { listId, added }) => ({
+  list: state.get('lists').get(listId),
+  added: typeof added === 'undefined' ? state.getIn(['listAdder', 'lists', 'items']).includes(listId) : added,
+});
+
+const mapDispatchToProps = (dispatch, { listId }) => ({
+  onRemove: () => dispatch(removeFromListAdder(listId)),
+  onAdd: () => dispatch(addToListAdder(listId)),
+});
+
+export default @connect(MapStateToProps, mapDispatchToProps)
+@injectIntl
+class List extends ImmutablePureComponent {
+
+  static propTypes = {
+    list: ImmutablePropTypes.map.isRequired,
+    intl: PropTypes.object.isRequired,
+    onRemove: PropTypes.func.isRequired,
+    onAdd: PropTypes.func.isRequired,
+    added: PropTypes.bool,
+  };
+
+  static defaultProps = {
+    added: false,
+  };
+
+  render () {
+    const { list, intl, onRemove, onAdd, added } = this.props;
+
+    let button;
+
+    if (added) {
+      button = <IconButton icon='times' title={intl.formatMessage(messages.remove)} onClick={onRemove} />;
+    } else {
+      button = <IconButton icon='plus' title={intl.formatMessage(messages.add)} onClick={onAdd} />;
+    }
+
+    return (
+      <div className='list'>
+        <div className='list__wrapper'>
+          <div className='list__display-name'>
+            <i className='fa fa-fw fa-list-ul column-link__icon' />
+            {list.get('title')}
+          </div>
+
+          <div className='account__relationship'>
+            {button}
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/list_adder/index.js b/app/javascript/mastodon/features/list_adder/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..cb8a15e8c7def8d12f008e462b53f882f18e7710
--- /dev/null
+++ b/app/javascript/mastodon/features/list_adder/index.js
@@ -0,0 +1,73 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { connect } from 'react-redux';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import { injectIntl } from 'react-intl';
+import { setupListAdder, resetListAdder } from '../../actions/lists';
+import { createSelector } from 'reselect';
+import List from './components/list';
+import Account from './components/account';
+import NewListForm from '../lists/components/new_list_form';
+// hack
+
+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')));
+});
+
+const mapStateToProps = state => ({
+  listIds: getOrderedLists(state).map(list=>list.get('id')),
+});
+
+const mapDispatchToProps = dispatch => ({
+  onInitialize: accountId => dispatch(setupListAdder(accountId)),
+  onReset: () => dispatch(resetListAdder()),
+});
+
+export default @connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
+class ListAdder extends ImmutablePureComponent {
+
+  static propTypes = {
+    accountId: PropTypes.string.isRequired,
+    onClose: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
+    onInitialize: PropTypes.func.isRequired,
+    onReset: PropTypes.func.isRequired,
+    listIds: ImmutablePropTypes.list.isRequired,
+  };
+
+  componentDidMount () {
+    const { onInitialize, accountId } = this.props;
+    onInitialize(accountId);
+  }
+
+  componentWillUnmount () {
+    const { onReset } = this.props;
+    onReset();
+  }
+
+  render () {
+    const { accountId, listIds } = this.props;
+
+    return (
+      <div className='modal-root__modal list-adder'>
+        <div className='list-adder__account'>
+          <Account accountId={accountId} />
+        </div>
+
+        <NewListForm />
+
+
+        <div className='list-adder__lists'>
+          {listIds.map(ListId => <List key={ListId} listId={ListId} />)}
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/list_editor/components/account.js b/app/javascript/mastodon/features/list_editor/components/account.js
index c78c58e244d7a44185affd92281097b1b9aaddd1..48085af43d1e7e4c89be728ed637fa56425cf38d 100644
--- a/app/javascript/mastodon/features/list_editor/components/account.js
+++ b/app/javascript/mastodon/features/list_editor/components/account.js
@@ -31,9 +31,9 @@ const mapDispatchToProps = (dispatch, { accountId }) => ({
   onAdd: () => dispatch(addToListEditor(accountId)),
 });
 
-@connect(makeMapStateToProps, mapDispatchToProps)
+export default @connect(makeMapStateToProps, mapDispatchToProps)
 @injectIntl
-export default class Account extends ImmutablePureComponent {
+class Account extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
diff --git a/app/javascript/mastodon/features/list_editor/components/search.js b/app/javascript/mastodon/features/list_editor/components/search.js
index 45c4d0f2ecde5a7ec21825ec9d9efb7436c8c12b..f7617fe5876a262e78b84365b04b0742287aa093 100644
--- a/app/javascript/mastodon/features/list_editor/components/search.js
+++ b/app/javascript/mastodon/features/list_editor/components/search.js
@@ -19,9 +19,9 @@ const mapDispatchToProps = dispatch => ({
   onChange: value => dispatch(changeListSuggestions(value)),
 });
 
-@connect(mapStateToProps, mapDispatchToProps)
+export default @connect(mapStateToProps, mapDispatchToProps)
 @injectIntl
-export default class Search extends React.PureComponent {
+class Search extends React.PureComponent {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
diff --git a/app/javascript/mastodon/features/list_editor/index.js b/app/javascript/mastodon/features/list_editor/index.js
index 65f7420de2de1a3f0efec758ad8f007b2bdf7aca..aab0cdd0c0cf3b49c8c1cfc283919a7d7d6e7059 100644
--- a/app/javascript/mastodon/features/list_editor/index.js
+++ b/app/javascript/mastodon/features/list_editor/index.js
@@ -22,9 +22,9 @@ const mapDispatchToProps = dispatch => ({
   onReset: () => dispatch(resetListEditor()),
 });
 
-@connect(mapStateToProps, mapDispatchToProps)
+export default @connect(mapStateToProps, mapDispatchToProps)
 @injectIntl
-export default class ListEditor extends ImmutablePureComponent {
+class ListEditor extends ImmutablePureComponent {
 
   static propTypes = {
     listId: PropTypes.string.isRequired,
diff --git a/app/javascript/mastodon/features/list_timeline/index.js b/app/javascript/mastodon/features/list_timeline/index.js
index f08e77b7a92d2dc14081ac9c7fd324f442674388..5b047ace483fdcb52948efb31801272e50130100 100644
--- a/app/javascript/mastodon/features/list_timeline/index.js
+++ b/app/javascript/mastodon/features/list_timeline/index.js
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import StatusListContainer from '../ui/containers/status_list_container';
 import Column from '../../components/column';
+import ColumnBackButton from '../../components/column_back_button';
 import ColumnHeader from '../../components/column_header';
 import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
@@ -24,9 +25,9 @@ const mapStateToProps = (state, props) => ({
   hasUnread: state.getIn(['timelines', `list:${props.params.id}`, 'unread']) > 0,
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class ListTimeline extends React.PureComponent {
+class ListTimeline extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -35,6 +36,7 @@ export default class ListTimeline extends React.PureComponent {
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     columnId: PropTypes.string,
     hasUnread: PropTypes.bool,
     multiColumn: PropTypes.bool,
@@ -112,7 +114,7 @@ export default class ListTimeline extends React.PureComponent {
   }
 
   render () {
-    const { hasUnread, columnId, multiColumn, list } = this.props;
+    const { shouldUpdateScroll, hasUnread, columnId, multiColumn, list } = this.props;
     const { id } = this.props.params;
     const pinned = !!columnId;
     const title  = list ? list.get('title') : id;
@@ -128,15 +130,14 @@ export default class ListTimeline extends React.PureComponent {
     } else if (list === false) {
       return (
         <Column>
-          <div className='scrollable'>
-            <MissingIndicator />
-          </div>
+          <ColumnBackButton />
+          <MissingIndicator />
         </Column>
       );
     }
 
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={title}>
         <ColumnHeader
           icon='list-ul'
           active={hasUnread}
@@ -166,6 +167,7 @@ export default class ListTimeline extends React.PureComponent {
           timelineId={`list:${id}`}
           onLoadMore={this.handleLoadMore}
           emptyMessage={<FormattedMessage id='empty_column.list' defaultMessage='There is nothing in this list yet. When members of this list post new statuses, they will appear here.' />}
+          shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
     );
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 eed6efc253a6b0ec12eda9a538f555dda67cd125..7392466401780ac0c80822d32cf9291cd54986f1 100644
--- a/app/javascript/mastodon/features/lists/components/new_list_form.js
+++ b/app/javascript/mastodon/features/lists/components/new_list_form.js
@@ -20,9 +20,9 @@ const mapDispatchToProps = dispatch => ({
   onSubmit: () => dispatch(submitListEditor(true)),
 });
 
-@connect(mapStateToProps, mapDispatchToProps)
+export default @connect(mapStateToProps, mapDispatchToProps)
 @injectIntl
-export default class NewListForm extends React.PureComponent {
+class NewListForm extends React.PureComponent {
 
   static propTypes = {
     value: PropTypes.string.isRequired,
diff --git a/app/javascript/mastodon/features/lists/index.js b/app/javascript/mastodon/features/lists/index.js
index 018e5a9e33efb1f0aa319162c384a881fc66e722..24f40c16b6d95153b9d2aae6d351615e675bc53e 100644
--- a/app/javascript/mastodon/features/lists/index.js
+++ b/app/javascript/mastodon/features/lists/index.js
@@ -6,12 +6,13 @@ import LoadingIndicator from '../../components/loading_indicator';
 import Column from '../ui/components/column';
 import ColumnBackButtonSlim from '../../components/column_back_button_slim';
 import { fetchLists } from '../../actions/lists';
-import { defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import ColumnLink from '../ui/components/column_link';
 import ColumnSubheading from '../ui/components/column_subheading';
 import NewListForm from './components/new_list_form';
 import { createSelector } from 'reselect';
+import ScrollableList from '../../components/scrollable_list';
 
 const messages = defineMessages({
   heading: { id: 'column.lists', defaultMessage: 'Lists' },
@@ -30,9 +31,9 @@ const mapStateToProps = state => ({
   lists: getOrderedLists(state),
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class Lists extends ImmutablePureComponent {
+class Lists extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -46,7 +47,7 @@ export default class Lists extends ImmutablePureComponent {
   }
 
   render () {
-    const { intl, lists } = this.props;
+    const { intl, shouldUpdateScroll, lists } = this.props;
 
     if (!lists) {
       return (
@@ -56,19 +57,24 @@ export default class Lists extends ImmutablePureComponent {
       );
     }
 
+    const emptyMessage = <FormattedMessage id='empty_column.lists' defaultMessage="You don't have any lists yet. When you create one, it will show up here." />;
+
     return (
       <Column icon='list-ul' heading={intl.formatMessage(messages.heading)}>
         <ColumnBackButtonSlim />
 
         <NewListForm />
 
-        <div className='scrollable'>
-          <ColumnSubheading text={intl.formatMessage(messages.subheading)} />
-
+        <ColumnSubheading text={intl.formatMessage(messages.subheading)} />
+        <ScrollableList
+          scrollKey='lists'
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={emptyMessage}
+        >
           {lists.map(list =>
             <ColumnLink key={list.get('id')} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />
           )}
-        </div>
+        </ScrollableList>
       </Column>
     );
   }
diff --git a/app/javascript/mastodon/features/mutes/index.js b/app/javascript/mastodon/features/mutes/index.js
index bb351ece24665d31bc8c023377e6a45204df0a3d..f979ef72f90fd519189b0a073df36e96e142cb52 100644
--- a/app/javascript/mastodon/features/mutes/index.js
+++ b/app/javascript/mastodon/features/mutes/index.js
@@ -1,15 +1,16 @@
 import React from 'react';
 import { connect } from 'react-redux';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import { debounce } from 'lodash';
 import LoadingIndicator from '../../components/loading_indicator';
-import { ScrollContainer } from 'react-router-scroll-4';
 import Column from '../ui/components/column';
 import ColumnBackButtonSlim from '../../components/column_back_button_slim';
 import AccountContainer from '../../containers/account_container';
 import { fetchMutes, expandMutes } from '../../actions/mutes';
-import { defineMessages, injectIntl } from 'react-intl';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import ScrollableList from '../../components/scrollable_list';
 
 const messages = defineMessages({
   heading: { id: 'column.mutes', defaultMessage: 'Muted users' },
@@ -19,13 +20,14 @@ const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'mutes', 'items']),
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class Mutes extends ImmutablePureComponent {
+class Mutes extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
     intl: PropTypes.object.isRequired,
   };
@@ -34,16 +36,12 @@ export default class Mutes extends ImmutablePureComponent {
     this.props.dispatch(fetchMutes());
   }
 
-  handleScroll = (e) => {
-    const { scrollTop, scrollHeight, clientHeight } = e.target;
-
-    if (scrollTop === scrollHeight - clientHeight) {
-      this.props.dispatch(expandMutes());
-    }
-  }
+  handleLoadMore = debounce(() => {
+    this.props.dispatch(expandMutes());
+  }, 300, { leading: true });
 
   render () {
-    const { intl, accountIds } = this.props;
+    const { intl, shouldUpdateScroll, accountIds } = this.props;
 
     if (!accountIds) {
       return (
@@ -53,16 +51,21 @@ export default class Mutes extends ImmutablePureComponent {
       );
     }
 
+    const emptyMessage = <FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />;
+
     return (
       <Column icon='volume-off' heading={intl.formatMessage(messages.heading)}>
         <ColumnBackButtonSlim />
-        <ScrollContainer scrollKey='mutes'>
-          <div className='scrollable mutes' onScroll={this.handleScroll}>
-            {accountIds.map(id =>
-              <AccountContainer key={id} id={id} />
-            )}
-          </div>
-        </ScrollContainer>
+        <ScrollableList
+          scrollKey='mutes'
+          onLoadMore={this.handleLoadMore}
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={emptyMessage}
+        >
+          {accountIds.map(id =>
+            <AccountContainer key={id} id={id} />
+          )}
+        </ScrollableList>
       </Column>
     );
   }
diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js
index d9638aaf35a958801501f74351cbf6f169091f96..a334fd63cc8fa7bf4c2c947d29efcabce05cefce 100644
--- a/app/javascript/mastodon/features/notifications/components/column_settings.js
+++ b/app/javascript/mastodon/features/notifications/components/column_settings.js
@@ -21,13 +21,14 @@ export default class ColumnSettings extends React.PureComponent {
   render () {
     const { settings, pushSettings, onChange, onClear } = this.props;
 
-    const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
-    const showStr  = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
-    const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
+    const filterShowStr = <FormattedMessage id='notifications.column_settings.filter_bar.show' defaultMessage='Show' />;
+    const filterAdvancedStr = <FormattedMessage id='notifications.column_settings.filter_bar.advanced' defaultMessage='Display all categories' />;
+    const alertStr  = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
+    const showStr   = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
+    const soundStr  = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
 
     const showPushSettings = pushSettings.get('browserSupport') && pushSettings.get('isSubscribed');
     const pushStr = showPushSettings && <FormattedMessage id='notifications.column_settings.push' defaultMessage='Push notifications' />;
-    const pushMeta = showPushSettings && <FormattedMessage id='notifications.column_settings.push_meta' defaultMessage='This device' />;
 
     return (
       <div>
@@ -35,12 +36,22 @@ export default class ColumnSettings extends React.PureComponent {
           <ClearColumnButton onClick={onClear} />
         </div>
 
+        <div role='group' aria-labelledby='notifications-filter-bar'>
+          <span id='notifications-filter-bar' className='column-settings__section'>
+            <FormattedMessage id='notifications.column_settings.filter_bar.category' defaultMessage='Quick filter bar' />
+          </span>
+          <div className='column-settings__row'>
+            <SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'show']} onChange={onChange} label={filterShowStr} />
+            <SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'advanced']} onChange={onChange} label={filterAdvancedStr} />
+          </div>
+        </div>
+
         <div role='group' aria-labelledby='notifications-follow'>
           <span id='notifications-follow' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span>
 
           <div className='column-settings__row'>
             <SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'follow']} onChange={onChange} label={alertStr} />
-            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'follow']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
+            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'follow']} onChange={this.onPushChange} label={pushStr} />}
             <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow']} onChange={onChange} label={showStr} />
             <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow']} onChange={onChange} label={soundStr} />
           </div>
@@ -51,7 +62,7 @@ export default class ColumnSettings extends React.PureComponent {
 
           <div className='column-settings__row'>
             <SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'favourite']} onChange={onChange} label={alertStr} />
-            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'favourite']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
+            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'favourite']} onChange={this.onPushChange} label={pushStr} />}
             <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'favourite']} onChange={onChange} label={showStr} />
             <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'favourite']} onChange={onChange} label={soundStr} />
           </div>
@@ -62,7 +73,7 @@ export default class ColumnSettings extends React.PureComponent {
 
           <div className='column-settings__row'>
             <SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'mention']} onChange={onChange} label={alertStr} />
-            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'mention']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
+            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'mention']} onChange={this.onPushChange} label={pushStr} />}
             <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'mention']} onChange={onChange} label={showStr} />
             <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'mention']} onChange={onChange} label={soundStr} />
           </div>
@@ -73,7 +84,7 @@ export default class ColumnSettings extends React.PureComponent {
 
           <div className='column-settings__row'>
             <SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'reblog']} onChange={onChange} label={alertStr} />
-            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'reblog']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
+            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'reblog']} onChange={this.onPushChange} label={pushStr} />}
             <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'reblog']} onChange={onChange} label={showStr} />
             <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'reblog']} onChange={onChange} label={soundStr} />
           </div>
diff --git a/app/javascript/mastodon/features/notifications/components/filter_bar.js b/app/javascript/mastodon/features/notifications/components/filter_bar.js
new file mode 100644
index 0000000000000000000000000000000000000000..f95a2c9dea695ad2f8b8d053e194a87c7072ce88
--- /dev/null
+++ b/app/javascript/mastodon/features/notifications/components/filter_bar.js
@@ -0,0 +1,93 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+
+const tooltips = defineMessages({
+  mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' },
+  favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favourites' },
+  boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' },
+  follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' },
+});
+
+export default @injectIntl
+class FilterBar extends React.PureComponent {
+
+  static propTypes = {
+    selectFilter: PropTypes.func.isRequired,
+    selectedFilter: PropTypes.string.isRequired,
+    advancedMode: PropTypes.bool.isRequired,
+    intl: PropTypes.object.isRequired,
+  };
+
+  onClick (notificationType) {
+    return () => this.props.selectFilter(notificationType);
+  }
+
+  render () {
+    const { selectedFilter, advancedMode, intl } = this.props;
+    const renderedElement = !advancedMode ? (
+      <div className='notification__filter-bar'>
+        <button
+          className={selectedFilter === 'all' ? 'active' : ''}
+          onClick={this.onClick('all')}
+        >
+          <FormattedMessage
+            id='notifications.filter.all'
+            defaultMessage='All'
+          />
+        </button>
+        <button
+          className={selectedFilter === 'mention' ? 'active' : ''}
+          onClick={this.onClick('mention')}
+        >
+          <FormattedMessage
+            id='notifications.filter.mentions'
+            defaultMessage='Mentions'
+          />
+        </button>
+      </div>
+    ) : (
+      <div className='notification__filter-bar'>
+        <button
+          className={selectedFilter === 'all' ? 'active' : ''}
+          onClick={this.onClick('all')}
+        >
+          <FormattedMessage
+            id='notifications.filter.all'
+            defaultMessage='All'
+          />
+        </button>
+        <button
+          className={selectedFilter === 'mention' ? 'active' : ''}
+          onClick={this.onClick('mention')}
+          title={intl.formatMessage(tooltips.mentions)}
+        >
+          <i className='fa fa-fw fa-at' />
+        </button>
+        <button
+          className={selectedFilter === 'favourite' ? 'active' : ''}
+          onClick={this.onClick('favourite')}
+          title={intl.formatMessage(tooltips.favourites)}
+        >
+          <i className='fa fa-fw fa-star' />
+        </button>
+        <button
+          className={selectedFilter === 'reblog' ? 'active' : ''}
+          onClick={this.onClick('reblog')}
+          title={intl.formatMessage(tooltips.boosts)}
+        >
+          <i className='fa fa-fw fa-retweet' />
+        </button>
+        <button
+          className={selectedFilter === 'follow' ? 'active' : ''}
+          onClick={this.onClick('follow')}
+          title={intl.formatMessage(tooltips.follows)}
+        >
+          <i className='fa fa-fw fa-user-plus' />
+        </button>
+      </div>
+    );
+    return renderedElement;
+  }
+
+}
diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js
index f58224a8b4f3f4e88613ffa848ae4f61a69d2382..44da423adcd6fdc63a30ddef653477e4abf930b7 100644
--- a/app/javascript/mastodon/features/notifications/components/notification.js
+++ b/app/javascript/mastodon/features/notifications/components/notification.js
@@ -3,12 +3,21 @@ import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import StatusContainer from '../../../containers/status_container';
 import AccountContainer from '../../../containers/account_container';
-import { FormattedMessage } from 'react-intl';
+import { injectIntl, FormattedMessage } from 'react-intl';
 import Permalink from '../../../components/permalink';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { HotKeys } from 'react-hotkeys';
 
-export default class Notification extends ImmutablePureComponent {
+const notificationForScreenReader = (intl, message, timestamp) => {
+  const output = [message];
+
+  output.push(intl.formatDate(timestamp, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }));
+
+  return output.join(', ');
+};
+
+export default @injectIntl
+class Notification extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -20,6 +29,7 @@ export default class Notification extends ImmutablePureComponent {
     onMoveUp: PropTypes.func.isRequired,
     onMoveDown: PropTypes.func.isRequired,
     onMention: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
   };
 
   handleMoveUp = () => {
@@ -65,16 +75,20 @@ export default class Notification extends ImmutablePureComponent {
     };
   }
 
-  renderFollow (account, link) {
+  renderFollow (notification, account, link) {
+    const { intl } = this.props;
+
     return (
       <HotKeys handlers={this.getHandlers()}>
-        <div className='notification notification-follow focusable' tabIndex='0'>
+        <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' />
             </div>
 
-            <FormattedMessage id='notification.follow' defaultMessage='{name} followed you' values={{ name: link }} />
+            <span title={notification.get('created_at')}>
+              <FormattedMessage id='notification.follow' defaultMessage='{name} followed you' values={{ name: link }} />
+            </span>
           </div>
 
           <AccountContainer id={account.get('id')} withNote={false} hidden={this.props.hidden} />
@@ -97,14 +111,19 @@ export default class Notification extends ImmutablePureComponent {
   }
 
   renderFavourite (notification, link) {
+    const { intl } = this.props;
+
     return (
       <HotKeys handlers={this.getHandlers()}>
-        <div className='notification notification-favourite focusable' tabIndex='0'>
+        <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' />
             </div>
-            <FormattedMessage id='notification.favourite' defaultMessage='{name} favourited your status' values={{ name: link }} />
+
+            <span title={notification.get('created_at')}>
+              <FormattedMessage id='notification.favourite' defaultMessage='{name} favourited your status' values={{ name: link }} />
+            </span>
           </div>
 
           <StatusContainer id={notification.get('status')} account={notification.get('account')} muted withDismiss hidden={!!this.props.hidden} />
@@ -114,14 +133,19 @@ export default class Notification extends ImmutablePureComponent {
   }
 
   renderReblog (notification, link) {
+    const { intl } = this.props;
+
     return (
       <HotKeys handlers={this.getHandlers()}>
-        <div className='notification notification-reblog focusable' tabIndex='0'>
+        <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' />
             </div>
-            <FormattedMessage id='notification.reblog' defaultMessage='{name} boosted your status' values={{ name: link }} />
+
+            <span title={notification.get('created_at')}>
+              <FormattedMessage id='notification.reblog' defaultMessage='{name} boosted your status' values={{ name: link }} />
+            </span>
           </div>
 
           <StatusContainer id={notification.get('status')} account={notification.get('account')} muted withDismiss hidden={this.props.hidden} />
@@ -138,7 +162,7 @@ export default class Notification extends ImmutablePureComponent {
 
     switch(notification.get('type')) {
     case 'follow':
-      return this.renderFollow(account, link);
+      return this.renderFollow(notification, account, link);
     case 'mention':
       return this.renderMention(notification);
     case 'favourite':
diff --git a/app/javascript/mastodon/features/notifications/components/setting_toggle.js b/app/javascript/mastodon/features/notifications/components/setting_toggle.js
index ac2211e48bddb1556e44700ed481918c033b757d..7aec16d2ea71ed267e21e94c3c2648ab8d65eb27 100644
--- a/app/javascript/mastodon/features/notifications/components/setting_toggle.js
+++ b/app/javascript/mastodon/features/notifications/components/setting_toggle.js
@@ -10,7 +10,6 @@ export default class SettingToggle extends React.PureComponent {
     settings: ImmutablePropTypes.map.isRequired,
     settingPath: PropTypes.array.isRequired,
     label: PropTypes.node.isRequired,
-    meta: PropTypes.node,
     onChange: PropTypes.func.isRequired,
   }
 
@@ -19,14 +18,13 @@ export default class SettingToggle extends React.PureComponent {
   }
 
   render () {
-    const { prefix, settings, settingPath, label, meta } = this.props;
+    const { prefix, settings, settingPath, label } = this.props;
     const id = ['setting-toggle', prefix, ...settingPath].filter(Boolean).join('-');
 
     return (
       <div className='setting-toggle'>
         <Toggle id={id} checked={settings.getIn(settingPath)} onChange={this.onChange} onKeyDown={this.onKeyDown} />
         <label htmlFor={id} className='setting-toggle__label'>{label}</label>
-        {meta && <span className='setting-meta__label'>{meta}</span>}
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js
index e9cef0a7bc300cd584964228667edfef4c5ca546..a67f262953f6a6c2ef6b6b93a1cfee1698825f89 100644
--- a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js
+++ b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js
@@ -2,6 +2,7 @@ import { connect } from 'react-redux';
 import { defineMessages, injectIntl } from 'react-intl';
 import ColumnSettings from '../components/column_settings';
 import { changeSetting } from '../../../actions/settings';
+import { setFilter } from '../../../actions/notifications';
 import { clearNotifications } from '../../../actions/notifications';
 import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications';
 import { openModal } from '../../../actions/modal';
@@ -21,6 +22,9 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
   onChange (path, checked) {
     if (path[0] === 'push') {
       dispatch(changePushNotifications(path.slice(1), checked));
+    } else if (path[0] === 'quickFilter') {
+      dispatch(changeSetting(['notifications', ...path], checked));
+      dispatch(setFilter('all'));
     } else {
       dispatch(changeSetting(['notifications', ...path], checked));
     }
diff --git a/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js b/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..4d495c2908126a130e8306a11fe74c171f834564
--- /dev/null
+++ b/app/javascript/mastodon/features/notifications/containers/filter_bar_container.js
@@ -0,0 +1,16 @@
+import { connect } from 'react-redux';
+import FilterBar from '../components/filter_bar';
+import { setFilter } from '../../../actions/notifications';
+
+const makeMapStateToProps = state => ({
+  selectedFilter: state.getIn(['settings', 'notifications', 'quickFilter', 'active']),
+  advancedMode: state.getIn(['settings', 'notifications', 'quickFilter', 'advanced']),
+});
+
+const mapDispatchToProps = (dispatch) => ({
+  selectFilter (newActiveFilter) {
+    dispatch(setFilter(newActiveFilter));
+  },
+});
+
+export default connect(makeMapStateToProps, mapDispatchToProps)(FilterBar);
diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js
index 94a46b833333776b12b4f3b822b834380cfe7c0a..9430b20505040a1d1023098b3c0c470d6d21f34e 100644
--- a/app/javascript/mastodon/features/notifications/index.js
+++ b/app/javascript/mastodon/features/notifications/index.js
@@ -9,6 +9,7 @@ import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 import NotificationContainer from './containers/notification_container';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ColumnSettingsContainer from './containers/column_settings_container';
+import FilterBarContainer from './containers/filter_bar_container';
 import { createSelector } from 'reselect';
 import { List as ImmutableList } from 'immutable';
 import { debounce } from 'lodash';
@@ -20,24 +21,36 @@ const messages = defineMessages({
 });
 
 const getNotifications = createSelector([
+  state => state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
+  state => state.getIn(['settings', 'notifications', 'quickFilter', 'active']),
   state => ImmutableList(state.getIn(['settings', 'notifications', 'shows']).filter(item => !item).keys()),
   state => state.getIn(['notifications', 'items']),
-], (excludedTypes, notifications) => notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type'))));
+], (showFilterBar, allowedType, excludedTypes, notifications) => {
+  if (!showFilterBar || allowedType === 'all') {
+    // used if user changed the notification settings after loading the notifications from the server
+    // otherwise a list of notifications will come pre-filtered from the backend
+    // we need to turn it off for FilterBar in order not to block ourselves from seeing a specific category
+    return notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type')));
+  }
+  return notifications.filter(item => item !== null && allowedType === item.get('type'));
+});
 
 const mapStateToProps = state => ({
+  showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
   notifications: getNotifications(state),
   isLoading: state.getIn(['notifications', 'isLoading'], true),
   isUnread: state.getIn(['notifications', 'unread']) > 0,
   hasMore: state.getIn(['notifications', 'hasMore']),
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class Notifications extends React.PureComponent {
+class Notifications extends React.PureComponent {
 
   static propTypes = {
     columnId: PropTypes.string,
     notifications: ImmutablePropTypes.list.isRequired,
+    showFilterBar: PropTypes.bool.isRequired,
     dispatch: PropTypes.func.isRequired,
     shouldUpdateScroll: PropTypes.func,
     intl: PropTypes.object.isRequired,
@@ -117,12 +130,16 @@ export default class Notifications extends React.PureComponent {
   }
 
   render () {
-    const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore } = this.props;
+    const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, showFilterBar } = this.props;
     const pinned = !!columnId;
     const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />;
 
     let scrollableContent = null;
 
+    const filterBarContainer = showFilterBar
+      ? (<FilterBarContainer />)
+      : null;
+
     if (isLoading && this.scrollableContent) {
       scrollableContent = this.scrollableContent;
     } else if (notifications.size > 0 || hasMore) {
@@ -153,6 +170,7 @@ export default class Notifications extends React.PureComponent {
         scrollKey={`notifications-${columnId}`}
         trackScroll={!pinned}
         isLoading={isLoading}
+        showLoading={isLoading && notifications.size === 0}
         hasMore={hasMore}
         emptyMessage={emptyMessage}
         onLoadMore={this.handleLoadOlder}
@@ -165,7 +183,7 @@ export default class Notifications extends React.PureComponent {
     );
 
     return (
-      <Column ref={this.setColumnRef}>
+      <Column ref={this.setColumnRef} label={intl.formatMessage(messages.title)}>
         <ColumnHeader
           icon='bell'
           active={isUnread}
@@ -178,7 +196,7 @@ export default class Notifications extends React.PureComponent {
         >
           <ColumnSettingsContainer />
         </ColumnHeader>
-
+        {filterBarContainer}
         {scrollContainer}
       </Column>
     );
diff --git a/app/javascript/mastodon/features/pinned_statuses/index.js b/app/javascript/mastodon/features/pinned_statuses/index.js
index b4a6c1e527ded4eba90b273b1ebcfd36053adfee..98cdbda3c492c0c6d3005ff532270fa38d98d5fb 100644
--- a/app/javascript/mastodon/features/pinned_statuses/index.js
+++ b/app/javascript/mastodon/features/pinned_statuses/index.js
@@ -18,12 +18,13 @@ const mapStateToProps = state => ({
   hasMore: !!state.getIn(['status_lists', 'pins', 'next']),
 });
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class PinnedStatuses extends ImmutablePureComponent {
+class PinnedStatuses extends ImmutablePureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     statusIds: ImmutablePropTypes.list.isRequired,
     intl: PropTypes.object.isRequired,
     hasMore: PropTypes.bool.isRequired,
@@ -42,7 +43,7 @@ export default class PinnedStatuses extends ImmutablePureComponent {
   }
 
   render () {
-    const { intl, statusIds, hasMore } = this.props;
+    const { intl, shouldUpdateScroll, statusIds, hasMore } = this.props;
 
     return (
       <Column icon='thumb-tack' heading={intl.formatMessage(messages.heading)} ref={this.setRef}>
@@ -51,6 +52,7 @@ export default class PinnedStatuses extends ImmutablePureComponent {
           statusIds={statusIds}
           scrollKey='pinned_statuses'
           hasMore={hasMore}
+          shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.js
index 2d5bb3baf75f520c1fb045ff236880fb1a3c450e..d640033ebb6f47b5b261e453ea457bb9cb0b00be 100644
--- a/app/javascript/mastodon/features/public_timeline/index.js
+++ b/app/javascript/mastodon/features/public_timeline/index.js
@@ -25,9 +25,9 @@ const mapStateToProps = (state, { onlyMedia, columnId }) => {
   };
 };
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
-export default class PublicTimeline extends React.PureComponent {
+class PublicTimeline extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -39,6 +39,7 @@ export default class PublicTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     intl: PropTypes.object.isRequired,
     columnId: PropTypes.string,
     multiColumn: PropTypes.bool,
@@ -99,19 +100,12 @@ export default class PublicTimeline extends React.PureComponent {
     dispatch(expandPublicTimeline({ maxId, onlyMedia }));
   }
 
-  handleSettingChanged = (key, checked) => {
-    const { columnId } = this.props;
-    if (!columnId && key[0] === 'other' && key[1] === 'onlyMedia') {
-      this.context.router.history.replace(`/timelines/public${checked ? '/media' : ''}`);
-    }
-  }
-
   render () {
-    const { intl, columnId, hasUnread, multiColumn, onlyMedia } = this.props;
+    const { intl, shouldUpdateScroll, columnId, hasUnread, multiColumn, onlyMedia } = this.props;
     const pinned = !!columnId;
 
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
         <ColumnHeader
           icon='globe'
           active={hasUnread}
@@ -122,7 +116,7 @@ export default class PublicTimeline extends React.PureComponent {
           pinned={pinned}
           multiColumn={multiColumn}
         >
-          <ColumnSettingsContainer onChange={this.handleSettingChanged} columnId={columnId} />
+          <ColumnSettingsContainer columnId={columnId} />
         </ColumnHeader>
 
         <StatusListContainer
@@ -131,6 +125,7 @@ export default class PublicTimeline extends React.PureComponent {
           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' />}
+          shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/reblogs/index.js b/app/javascript/mastodon/features/reblogs/index.js
index 579d6aaa02343b0271f4a72be620f94f48468792..c05d21c740451c9dd6753deea26ce0c373446150 100644
--- a/app/javascript/mastodon/features/reblogs/index.js
+++ b/app/javascript/mastodon/features/reblogs/index.js
@@ -1,25 +1,27 @@
 import React from 'react';
 import { connect } from 'react-redux';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import LoadingIndicator from '../../components/loading_indicator';
 import { fetchReblogs } from '../../actions/interactions';
-import { ScrollContainer } from 'react-router-scroll-4';
+import { FormattedMessage } from 'react-intl';
 import AccountContainer from '../../containers/account_container';
 import Column from '../ui/components/column';
 import ColumnBackButton from '../../components/column_back_button';
-import ImmutablePureComponent from 'react-immutable-pure-component';
+import ScrollableList from '../../components/scrollable_list';
 
 const mapStateToProps = (state, props) => ({
   accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]),
 });
 
-@connect(mapStateToProps)
-export default class Reblogs extends ImmutablePureComponent {
+export default @connect(mapStateToProps)
+class Reblogs extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
+    shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
   };
 
@@ -34,7 +36,7 @@ export default class Reblogs extends ImmutablePureComponent {
   }
 
   render () {
-    const { accountIds } = this.props;
+    const { shouldUpdateScroll, accountIds } = this.props;
 
     if (!accountIds) {
       return (
@@ -44,15 +46,21 @@ export default class Reblogs extends ImmutablePureComponent {
       );
     }
 
+    const emptyMessage = <FormattedMessage id='status.reblogs.empty' defaultMessage='No one has boosted this toot yet. When someone does, they will show up here.' />;
+
     return (
       <Column>
         <ColumnBackButton />
 
-        <ScrollContainer scrollKey='reblogs'>
-          <div className='scrollable reblogs'>
-            {accountIds.map(id => <AccountContainer key={id} id={id} withNote={false} />)}
-          </div>
-        </ScrollContainer>
+        <ScrollableList
+          scrollKey='reblogs'
+          shouldUpdateScroll={shouldUpdateScroll}
+          emptyMessage={emptyMessage}
+        >
+          {accountIds.map(id =>
+            <AccountContainer key={id} id={id} withNote={false} />
+          )}
+        </ScrollableList>
       </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 9ff75a082c2ed1b6eb0966e83e8849a1f0eba2df..2552d94d899c9c8d9f60d5aba4f829697b28dc16 100644
--- a/app/javascript/mastodon/features/report/components/status_check_box.js
+++ b/app/javascript/mastodon/features/report/components/status_check_box.js
@@ -36,6 +36,7 @@ export default class StatusCheckBox extends React.PureComponent {
               <Component
                 preview={video.get('preview_url')}
                 src={video.get('url')}
+                alt={video.get('description')}
                 width={239}
                 height={110}
                 inline
diff --git a/app/javascript/mastodon/features/standalone/community_timeline/index.js b/app/javascript/mastodon/features/standalone/community_timeline/index.js
index 629d058a26c0407397d5f8d70bc1f7712a380255..f917f41c974a2dbe6e4789783931ab22881c62f6 100644
--- a/app/javascript/mastodon/features/standalone/community_timeline/index.js
+++ b/app/javascript/mastodon/features/standalone/community_timeline/index.js
@@ -12,9 +12,9 @@ const messages = defineMessages({
   title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' },
 });
 
-@connect()
+export default @connect()
 @injectIntl
-export default class CommunityTimeline extends React.PureComponent {
+class CommunityTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -51,7 +51,7 @@ export default class CommunityTimeline extends React.PureComponent {
     const { intl } = this.props;
 
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
         <ColumnHeader
           icon='users'
           title={intl.formatMessage(messages.title)}
diff --git a/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js b/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js
index 931ca2a32ea727710aa5ad19c40643f6c54e6dff..333726f94225d91c946a10b1eb41243f5f161a9d 100644
--- a/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js
+++ b/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js
@@ -1,33 +1,37 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
-import StatusListContainer from '../../ui/containers/status_list_container';
+import ImmutablePropTypes from 'react-immutable-proptypes';
 import { expandHashtagTimeline } from '../../../actions/timelines';
-import Column from '../../../components/column';
-import ColumnHeader from '../../../components/column_header';
 import { connectHashtagStream } from '../../../actions/streaming';
+import Masonry from 'react-masonry-infinite';
+import { List as ImmutableList } from 'immutable';
+import DetailedStatusContainer from '../../status/containers/detailed_status_container';
+import { debounce } from 'lodash';
+import LoadingIndicator from '../../../components/loading_indicator';
 
-@connect()
-export default class HashtagTimeline extends React.PureComponent {
+const mapStateToProps = (state, { hashtag }) => ({
+  statusIds: state.getIn(['timelines', `hashtag:${hashtag}`, 'items'], ImmutableList()),
+  isLoading: state.getIn(['timelines', `hashtag:${hashtag}`, 'isLoading'], false),
+  hasMore: state.getIn(['timelines', `hashtag:${hashtag}`, 'hasMore'], false),
+});
+
+export default @connect(mapStateToProps)
+class HashtagTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
+    statusIds: ImmutablePropTypes.list.isRequired,
+    isLoading: PropTypes.bool.isRequired,
+    hasMore: PropTypes.bool.isRequired,
     hashtag: PropTypes.string.isRequired,
   };
 
-  handleHeaderClick = () => {
-    this.column.scrollTop();
-  }
-
-  setRef = c => {
-    this.column = c;
-  }
-
   componentDidMount () {
     const { dispatch, hashtag } = this.props;
 
     dispatch(expandHashtagTimeline(hashtag));
-    this.disconnect = dispatch(connectHashtagStream(hashtag));
+    this.disconnect = dispatch(connectHashtagStream(hashtag, hashtag));
   }
 
   componentWillUnmount () {
@@ -37,28 +41,52 @@ export default class HashtagTimeline extends React.PureComponent {
     }
   }
 
-  handleLoadMore = maxId => {
-    this.props.dispatch(expandHashtagTimeline(this.props.hashtag, { maxId }));
+  handleLoadMore = () => {
+    const maxId = this.props.statusIds.last();
+
+    if (maxId) {
+      this.props.dispatch(expandHashtagTimeline(this.props.hashtag, { maxId }));
+    }
+  }
+
+  setRef = c => {
+    this.masonry = c;
   }
 
+  handleHeightChange = debounce(() => {
+    if (!this.masonry) {
+      return;
+    }
+
+    this.masonry.forcePack();
+  }, 50)
+
   render () {
-    const { hashtag } = 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}>
-        <ColumnHeader
-          icon='hashtag'
-          title={hashtag}
-          onClick={this.handleHeaderClick}
-        />
-
-        <StatusListContainer
-          trackScroll={false}
-          scrollKey='standalone_hashtag_timeline'
-          timelineId={`hashtag:${hashtag}`}
-          onLoadMore={this.handleLoadMore}
-        />
-      </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/standalone/public_timeline/index.js b/app/javascript/mastodon/features/standalone/public_timeline/index.js
index 1236cb92730f5640aa6ce9a0f3e9524eaac74f27..618696eb167f5412874b51fe8769e7cc996d782d 100644
--- a/app/javascript/mastodon/features/standalone/public_timeline/index.js
+++ b/app/javascript/mastodon/features/standalone/public_timeline/index.js
@@ -12,9 +12,9 @@ const messages = defineMessages({
   title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' },
 });
 
-@connect()
+export default @connect()
 @injectIntl
-export default class PublicTimeline extends React.PureComponent {
+class PublicTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -51,7 +51,7 @@ export default class PublicTimeline extends React.PureComponent {
     const { intl } = this.props;
 
     return (
-      <Column ref={this.setRef}>
+      <Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
         <ColumnHeader
           icon='globe'
           title={intl.formatMessage(messages.title)}
diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js
index 5414996681761441f8c698df38689bd04080f0a9..d3b725283ad74d0178ca375e38fde8b9dd4dfdd1 100644
--- a/app/javascript/mastodon/features/status/components/action_bar.js
+++ b/app/javascript/mastodon/features/status/components/action_bar.js
@@ -4,7 +4,7 @@ import IconButton from '../../../components/icon_button';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
 import { defineMessages, injectIntl } from 'react-intl';
-import { me } from '../../../initial_state';
+import { me, isStaff } from '../../../initial_state';
 
 const messages = defineMessages({
   delete: { id: 'status.delete', defaultMessage: 'Delete' },
@@ -26,10 +26,12 @@ const messages = defineMessages({
   pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
   unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
   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' },
 });
 
-@injectIntl
-export default class ActionBar extends React.PureComponent {
+export default @injectIntl
+class ActionBar extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -65,11 +67,11 @@ export default class ActionBar extends React.PureComponent {
   }
 
   handleDeleteClick = () => {
-    this.props.onDelete(this.props.status);
+    this.props.onDelete(this.props.status, this.context.router.history);
   }
 
   handleRedraftClick = () => {
-    this.props.onDelete(this.props.status, true);
+    this.props.onDelete(this.props.status, this.context.router.history, true);
   }
 
   handleDirectClick = () => {
@@ -145,12 +147,24 @@ export default class ActionBar extends React.PureComponent {
       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'])}` });
+        menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
+      }
     }
 
     const shareButton = ('share' in navigator) && status.get('visibility') === 'public' && (
       <div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.share)} icon='share-alt' onClick={this.handleShare} /></div>
     );
 
+    let replyIcon;
+    if (status.get('in_reply_to_id', null) === null) {
+      replyIcon = 'reply';
+    } else {
+      replyIcon = 'reply-all';
+    }
+
     let reblogIcon = 'retweet';
     if (status.get('visibility') === 'direct') reblogIcon = 'envelope';
     else if (status.get('visibility') === 'private') reblogIcon = 'lock';
@@ -159,7 +173,7 @@ export default class ActionBar extends React.PureComponent {
 
     return (
       <div className='detailed-status__action-bar'>
-        <div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_id', null) === null ? 'reply' : 'reply-all'} onClick={this.handleReplyClick} /></div>
+        <div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} /></div>
         <div className='detailed-status__button'><IconButton disabled={reblog_disabled} active={status.get('reblogged')} title={reblog_disabled ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} /></div>
         <div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} /></div>
         {shareButton}
diff --git a/app/javascript/mastodon/features/status/components/card.js b/app/javascript/mastodon/features/status/components/card.js
index b52f3c4fafd4689af84ae3ce0923407c8f8d8bbd..8491299ef49c68d1bf3128efa74f8e36a7d02c13 100644
--- a/app/javascript/mastodon/features/status/components/card.js
+++ b/app/javascript/mastodon/features/status/components/card.js
@@ -59,10 +59,12 @@ export default class Card extends React.PureComponent {
     card: ImmutablePropTypes.map,
     maxDescription: PropTypes.number,
     onOpenMedia: PropTypes.func.isRequired,
+    compact: PropTypes.bool,
   };
 
   static defaultProps = {
     maxDescription: 50,
+    compact: false,
   };
 
   state = {
@@ -71,7 +73,7 @@ export default class Card extends React.PureComponent {
   };
 
   componentWillReceiveProps (nextProps) {
-    if (this.props.card !== nextProps.card) {
+    if (!Immutable.is(this.props.card, nextProps.card)) {
       this.setState({ embedded: false });
     }
   }
@@ -118,7 +120,7 @@ export default class Card extends React.PureComponent {
     const content   = { __html: addAutoPlay(card.get('html')) };
     const { width } = this.state;
     const ratio     = card.get('width') / card.get('height');
-    const height    = card.get('width') > card.get('height') ? (width / ratio) : (width * ratio);
+    const height    = width / ratio;
 
     return (
       <div
@@ -131,25 +133,25 @@ export default class Card extends React.PureComponent {
   }
 
   render () {
-    const { card, maxDescription } = this.props;
-    const { width, embedded }      = this.state;
+    const { card, maxDescription, compact } = this.props;
+    const { width, embedded } = this.state;
 
     if (card === null) {
       return null;
     }
 
     const provider    = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name');
-    const horizontal  = card.get('width') > card.get('height') && (card.get('width') + 100 >= width) || card.get('type') !== 'link';
-    const className   = classnames('status-card', { horizontal });
+    const horizontal  = (!compact && card.get('width') > card.get('height') && (card.get('width') + 100 >= width)) || card.get('type') !== 'link' || embedded;
     const interactive = card.get('type') !== 'link';
+    const className   = classnames('status-card', { horizontal, compact, interactive });
     const title       = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
     const ratio       = card.get('width') / card.get('height');
-    const height      = card.get('width') > card.get('height') ? (width / ratio) : (width * ratio);
+    const height      = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
 
     const description = (
       <div className='status-card__content'>
         {title}
-        {!horizontal && <p className='status-card__description'>{trim(card.get('description') || '', maxDescription)}</p>}
+        {!(horizontal || compact) && <p className='status-card__description'>{trim(card.get('description') || '', maxDescription)}</p>}
         <span className='status-card__host'>{provider}</span>
       </div>
     );
@@ -174,7 +176,7 @@ export default class Card extends React.PureComponent {
             <div className='status-card__actions'>
               <div>
                 <button onClick={this.handleEmbedClick}><i className={`fa fa-${iconVariant}`} /></button>
-                <a href={card.get('url')} target='_blank' rel='noopener'><i className='fa fa-external-link' /></a>
+                {horizontal && <a href={card.get('url')} target='_blank' rel='noopener'><i className='fa fa-external-link' /></a>}
               </div>
             </div>
           </div>
@@ -184,7 +186,7 @@ export default class Card extends React.PureComponent {
       return (
         <div className={className} ref={this.setRef}>
           {embed}
-          {description}
+          {!compact && description}
         </div>
       );
     } else if (card.get('image')) {
@@ -193,6 +195,12 @@ export default class Card extends React.PureComponent {
           {thumbnail}
         </div>
       );
+    } else {
+      embed = (
+        <div className='status-card__image'>
+          <i className='fa fa-file-text' />
+        </div>
+      );
     }
 
     return (
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index 4177190044ee5266e7e88038fd0efb7ee9ce2e22..0630387d297745febbf454132ad1c4e1a6705a50 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -8,9 +8,11 @@ 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 CardContainer from '../containers/card_container';
+import Card from './card';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import Video from '../../video';
+import scheduleIdleTask from '../../ui/util/schedule_idle_task';
+import classNames from 'classnames';
 
 export default class DetailedStatus extends ImmutablePureComponent {
 
@@ -23,10 +25,18 @@ export default class DetailedStatus extends ImmutablePureComponent {
     onOpenMedia: PropTypes.func.isRequired,
     onOpenVideo: PropTypes.func.isRequired,
     onToggleHidden: PropTypes.func.isRequired,
+    measureHeight: PropTypes.bool,
+    onHeightChange: PropTypes.func,
+    domain: PropTypes.string.isRequired,
+    compact: PropTypes.bool,
+  };
+
+  state = {
+    height: null,
   };
 
   handleAccountClick = (e) => {
-    if (e.button === 0) {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey) && this.context.router) {
       e.preventDefault();
       this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
     }
@@ -42,13 +52,57 @@ export default class DetailedStatus extends ImmutablePureComponent {
     this.props.onToggleHidden(this.props.status);
   }
 
+  _measureHeight (heightJustChanged) {
+    if (this.props.measureHeight && this.node) {
+      scheduleIdleTask(() => this.node && this.setState({ height: Math.ceil(this.node.scrollHeight) + 1 }));
+
+      if (this.props.onHeightChange && heightJustChanged) {
+        this.props.onHeightChange();
+      }
+    }
+  }
+
+  setRef = c => {
+    this.node = c;
+    this._measureHeight();
+  }
+
+  componentDidUpdate (prevProps, prevState) {
+    this._measureHeight(prevState.height !== this.state.height);
+  }
+
+  handleModalLink = e => {
+    e.preventDefault();
+
+    let href;
+
+    if (e.target.nodeName !== 'A') {
+      href = e.target.parentNode.href;
+    } else {
+      href = e.target.href;
+    }
+
+    window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
+  }
+
   render () {
     const status = this.props.status.get('reblog') ? this.props.status.get('reblog') : this.props.status;
+    const outerStyle = { boxSizing: 'border-box' };
+    const { compact } = this.props;
+
+    if (!status) {
+      return null;
+    }
 
     let media           = '';
     let applicationLink = '';
     let reblogLink = '';
     let reblogIcon = 'retweet';
+    let favouriteLink = '';
+
+    if (this.props.measureHeight) {
+      outerStyle.height = `${this.state.height}px`;
+    }
 
     if (status.get('media_attachments').size > 0) {
       if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
@@ -60,6 +114,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
           <Video
             preview={video.get('preview_url')}
             src={video.get('url')}
+            alt={video.get('description')}
             width={300}
             height={150}
             inline
@@ -79,7 +134,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
         );
       }
     } else if (status.get('spoiler_text').length === 0) {
-      media = <CardContainer onOpenMedia={this.props.onOpenMedia} statusId={status.get('id')} />;
+      media = <Card onOpenMedia={this.props.onOpenMedia} card={status.get('card', null)} />;
     }
 
     if (status.get('application')) {
@@ -94,35 +149,63 @@ export default class DetailedStatus extends ImmutablePureComponent {
 
     if (status.get('visibility') === 'private') {
       reblogLink = <i className={`fa fa-${reblogIcon}`} />;
+    } else if (this.context.router) {
+      reblogLink = (
+        <Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
+          <i className={`fa fa-${reblogIcon}`} />
+          <span className='detailed-status__reblogs'>
+            <FormattedNumber value={status.get('reblogs_count')} />
+          </span>
+        </Link>
+      );
     } else {
-      reblogLink = (<Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
-        <i className={`fa fa-${reblogIcon}`} />
-        <span className='detailed-status__reblogs'>
-          <FormattedNumber value={status.get('reblogs_count')} />
-        </span>
-      </Link>);
+      reblogLink = (
+        <a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
+          <i className={`fa fa-${reblogIcon}`} />
+          <span className='detailed-status__reblogs'>
+            <FormattedNumber value={status.get('reblogs_count')} />
+          </span>
+        </a>
+      );
     }
 
-    return (
-      <div className='detailed-status'>
-        <a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
-          <div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
-          <DisplayName account={status.get('account')} />
+    if (this.context.router) {
+      favouriteLink = (
+        <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
+          <i className='fa fa-star' />
+          <span className='detailed-status__favorites'>
+            <FormattedNumber value={status.get('favourites_count')} />
+          </span>
+        </Link>
+      );
+    } else {
+      favouriteLink = (
+        <a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}>
+          <i className='fa fa-star' />
+          <span className='detailed-status__favorites'>
+            <FormattedNumber value={status.get('favourites_count')} />
+          </span>
         </a>
+      );
+    }
 
-        <StatusContent status={status} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} />
-
-        {media}
-
-        <div className='detailed-status__meta'>
-          <a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
-            <FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
-          </a>{applicationLink} · {reblogLink} · <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
-            <i className='fa fa-star' />
-            <span className='detailed-status__favorites'>
-              <FormattedNumber value={status.get('favourites_count')} />
-            </span>
-          </Link>
+    return (
+      <div style={outerStyle}>
+        <div ref={this.setRef} className={classNames('detailed-status', { compact })}>
+          <a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
+            <div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
+            <DisplayName account={status.get('account')} localDomain={this.props.domain} />
+          </a>
+
+          <StatusContent status={status} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} />
+
+          {media}
+
+          <div className='detailed-status__meta'>
+            <a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
+              <FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
+            </a>{applicationLink} · {reblogLink} · {favouriteLink}
+          </div>
         </div>
       </div>
     );
diff --git a/app/javascript/mastodon/features/status/containers/card_container.js b/app/javascript/mastodon/features/status/containers/card_container.js
deleted file mode 100644
index a97404de1903b2b71b5b3a1b0260a274faf2a49d..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/features/status/containers/card_container.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { connect } from 'react-redux';
-import Card from '../components/card';
-
-const mapStateToProps = (state, { statusId }) => ({
-  card: state.getIn(['cards', statusId], null),
-});
-
-export default connect(mapStateToProps)(Card);
diff --git a/app/javascript/mastodon/features/status/containers/detailed_status_container.js b/app/javascript/mastodon/features/status/containers/detailed_status_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..2c0db0a6b23e7d7835157c1b1307db8fc6f2be59
--- /dev/null
+++ b/app/javascript/mastodon/features/status/containers/detailed_status_container.js
@@ -0,0 +1,172 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import DetailedStatus from '../components/detailed_status';
+import { makeGetStatus } from '../../../selectors';
+import {
+  replyCompose,
+  mentionCompose,
+  directCompose,
+} from '../../../actions/compose';
+import {
+  reblog,
+  favourite,
+  unreblog,
+  unfavourite,
+  pin,
+  unpin,
+} from '../../../actions/interactions';
+import { blockAccount } from '../../../actions/accounts';
+import {
+  muteStatus,
+  unmuteStatus,
+  deleteStatus,
+  hideStatus,
+  revealStatus,
+} from '../../../actions/statuses';
+import { initMuteModal } from '../../../actions/mutes';
+import { initReport } from '../../../actions/reports';
+import { openModal } from '../../../actions/modal';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import { boostModal, deleteModal } from '../../../initial_state';
+import { showAlertForError } from '../../../actions/alerts';
+
+const messages = defineMessages({
+  deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
+  deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
+  redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
+  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: '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.' },
+  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?' },
+});
+
+const makeMapStateToProps = () => {
+  const getStatus = makeGetStatus();
+
+  const mapStateToProps = (state, props) => ({
+    status: getStatus(state, props),
+    domain: state.getIn(['meta', 'domain']),
+  });
+
+  return mapStateToProps;
+};
+
+const mapDispatchToProps = (dispatch, { intl }) => ({
+
+  onReply (status, router) {
+    dispatch((_, getState) => {
+      let state = getState();
+      if (state.getIn(['compose', 'text']).trim().length !== 0) {
+        dispatch(openModal('CONFIRM', {
+          message: intl.formatMessage(messages.replyMessage),
+          confirm: intl.formatMessage(messages.replyConfirm),
+          onConfirm: () => dispatch(replyCompose(status, router)),
+        }));
+      } else {
+        dispatch(replyCompose(status, 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));
+    }
+  },
+
+  onPin (status) {
+    if (status.get('pinned')) {
+      dispatch(unpin(status));
+    } else {
+      dispatch(pin(status));
+    }
+  },
+
+  onEmbed (status) {
+    dispatch(openModal('EMBED', {
+      url: status.get('url'),
+      onError: error => dispatch(showAlertForError(error)),
+    }));
+  },
+
+  onDelete (status, history, withRedraft = false) {
+    if (!deleteModal) {
+      dispatch(deleteStatus(status.get('id'), history, withRedraft));
+    } else {
+      dispatch(openModal('CONFIRM', {
+        message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
+        confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
+        onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
+      }));
+    }
+  },
+
+  onDirect (account, router) {
+    dispatch(directCompose(account, router));
+  },
+
+  onMention (account, router) {
+    dispatch(mentionCompose(account, router));
+  },
+
+  onOpenMedia (media, index) {
+    dispatch(openModal('MEDIA', { media, index }));
+  },
+
+  onOpenVideo (media, time) {
+    dispatch(openModal('VIDEO', { media, time }));
+  },
+
+  onBlock (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'))),
+    }));
+  },
+
+  onReport (status) {
+    dispatch(initReport(status.get('account'), status));
+  },
+
+  onMute (account) {
+    dispatch(initMuteModal(account));
+  },
+
+  onMuteConversation (status) {
+    if (status.get('muted')) {
+      dispatch(unmuteStatus(status.get('id')));
+    } else {
+      dispatch(muteStatus(status.get('id')));
+    }
+  },
+
+  onToggleHidden (status) {
+    if (status.get('hidden')) {
+      dispatch(revealStatus(status.get('id')));
+    } else {
+      dispatch(hideStatus(status.get('id')));
+    }
+  },
+
+});
+
+export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(DetailedStatus));
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index d7b50786cfd374f04b34b23692cba6c35d009838..d48b682ebbc22303bdeca152a177627bfdfc9523 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -42,16 +42,20 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { HotKeys } from 'react-hotkeys';
 import { boostModal, deleteModal } from '../../initial_state';
-import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../../features/ui/util/fullscreen';
+import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen';
+import { textForScreenReader } from '../../components/status';
 
 const messages = defineMessages({
   deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
   deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
   redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
-  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.' },
+  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: '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.' },
   blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
   revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' },
   hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' },
+  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?' },
 });
 
 const makeMapStateToProps = () => {
@@ -96,15 +100,17 @@ const makeMapStateToProps = () => {
       status,
       ancestorsIds,
       descendantsIds,
+      askReplyConfirmation: state.getIn(['compose', 'text']).trim().length !== 0,
+      domain: state.getIn(['meta', 'domain']),
     };
   };
 
   return mapStateToProps;
 };
 
-@injectIntl
+export default @injectIntl
 @connect(makeMapStateToProps)
-export default class Status extends ImmutablePureComponent {
+class Status extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -117,6 +123,8 @@ export default class Status extends ImmutablePureComponent {
     ancestorsIds: ImmutablePropTypes.list,
     descendantsIds: ImmutablePropTypes.list,
     intl: PropTypes.object.isRequired,
+    askReplyConfirmation: PropTypes.bool,
+    domain: PropTypes.string.isRequired,
   };
 
   state = {
@@ -155,7 +163,16 @@ export default class Status extends ImmutablePureComponent {
   }
 
   handleReplyClick = (status) => {
-    this.props.dispatch(replyCompose(status, this.context.router.history));
+    let { askReplyConfirmation, dispatch, intl } = this.props;
+    if (askReplyConfirmation) {
+      dispatch(openModal('CONFIRM', {
+        message: intl.formatMessage(messages.replyMessage),
+        confirm: intl.formatMessage(messages.replyConfirm),
+        onConfirm: () => dispatch(replyCompose(status, this.context.router.history)),
+      }));
+    } else {
+      dispatch(replyCompose(status, this.context.router.history));
+    }
   }
 
   handleModalReblog = (status) => {
@@ -166,7 +183,7 @@ export default class Status extends ImmutablePureComponent {
     if (status.get('reblogged')) {
       this.props.dispatch(unreblog(status));
     } else {
-      if (e.shiftKey || !boostModal) {
+      if ((e && e.shiftKey) || !boostModal) {
         this.handleModalReblog(status);
       } else {
         this.props.dispatch(openModal('BOOST', { status, onReblog: this.handleModalReblog }));
@@ -174,16 +191,16 @@ export default class Status extends ImmutablePureComponent {
     }
   }
 
-  handleDeleteClick = (status, withRedraft = false) => {
+  handleDeleteClick = (status, history, withRedraft = false) => {
     const { dispatch, intl } = this.props;
 
     if (!deleteModal) {
-      dispatch(deleteStatus(status.get('id'), withRedraft));
+      dispatch(deleteStatus(status.get('id'), history, withRedraft));
     } else {
       dispatch(openModal('CONFIRM', {
         message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
         confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
-        onConfirm: () => dispatch(deleteStatus(status.get('id'), withRedraft)),
+        onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
       }));
     }
   }
@@ -355,7 +372,9 @@ export default class Status extends ImmutablePureComponent {
     if (status && ancestorsIds && ancestorsIds.size > 0) {
       const element = this.node.querySelectorAll('.focusable')[ancestorsIds.size - 1];
 
-      element.scrollIntoView(true);
+      window.requestAnimationFrame(() => {
+        element.scrollIntoView(true);
+      });
       this._scrolledIntoView = true;
     }
   }
@@ -370,7 +389,7 @@ export default class Status extends ImmutablePureComponent {
 
   render () {
     let ancestors, descendants;
-    const { status, ancestorsIds, descendantsIds, intl } = this.props;
+    const { shouldUpdateScroll, status, ancestorsIds, descendantsIds, intl, domain } = this.props;
     const { fullscreen } = this.state;
 
     if (status === null) {
@@ -402,7 +421,7 @@ export default class Status extends ImmutablePureComponent {
     };
 
     return (
-      <Column>
+      <Column label={intl.formatMessage(messages.detailedStatus)}>
         <ColumnHeader
           showBackButton
           extraButton={(
@@ -410,17 +429,18 @@ export default class Status extends ImmutablePureComponent {
           )}
         />
 
-        <ScrollContainer scrollKey='thread'>
-          <div className={classNames('scrollable', 'detailed-status__wrapper', { fullscreen })} ref={this.setRef}>
+        <ScrollContainer scrollKey='thread' shouldUpdateScroll={shouldUpdateScroll}>
+          <div className={classNames('scrollable', { fullscreen })} ref={this.setRef}>
             {ancestors}
 
             <HotKeys handlers={handlers}>
-              <div className='focusable' tabIndex='0'>
+              <div className={classNames('focusable', 'detailed-status__wrapper')} tabIndex='0' aria-label={textForScreenReader(intl, status, false, !status.get('hidden'))}>
                 <DetailedStatus
                   status={status}
                   onOpenVideo={this.handleOpenVideo}
                   onOpenMedia={this.handleOpenMedia}
                   onToggleHidden={this.handleToggleHidden}
+                  domain={domain}
                 />
 
                 <ActionBar
diff --git a/app/javascript/mastodon/features/trends/index.js b/app/javascript/mastodon/features/trends/index.js
deleted file mode 100644
index f33af3e2e3fb45aeb8b61d0111ba84d2e2d82048..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/features/trends/index.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-import { connect } from 'react-redux';
-import { injectIntl, defineMessages } from 'react-intl';
-import Column from '../ui/components/column';
-import ColumnHeader from '../../components/column_header';
-import Hashtag from '../../components/hashtag';
-import classNames from 'classnames';
-import { fetchTrends } from '../../actions/trends';
-
-const messages = defineMessages({
-  title: { id: 'trends.header', defaultMessage: 'Trending now' },
-  refreshTrends: { id: 'trends.refresh', defaultMessage: 'Refresh trends' },
-});
-
-const mapStateToProps = state => ({
-  trends: state.getIn(['trends', 'items']),
-  loading: state.getIn(['trends', 'isLoading']),
-});
-
-const mapDispatchToProps = dispatch => ({
-  fetchTrends: () => dispatch(fetchTrends()),
-});
-
-@connect(mapStateToProps, mapDispatchToProps)
-@injectIntl
-export default class Trends extends ImmutablePureComponent {
-
-  static propTypes = {
-    intl: PropTypes.object.isRequired,
-    trends: ImmutablePropTypes.list,
-    fetchTrends: PropTypes.func.isRequired,
-    loading: PropTypes.bool,
-  };
-
-  componentDidMount () {
-    this.props.fetchTrends();
-  }
-
-  handleRefresh = () => {
-    this.props.fetchTrends();
-  }
-
-  render () {
-    const { trends, loading, intl } = this.props;
-
-    return (
-      <Column>
-        <ColumnHeader
-          icon='fire'
-          title={intl.formatMessage(messages.title)}
-          extraButton={(
-            <button className='column-header__button' title={intl.formatMessage(messages.refreshTrends)} aria-label={intl.formatMessage(messages.refreshTrends)} onClick={this.handleRefresh}><i className={classNames('fa', 'fa-refresh', { 'fa-spin': loading })} /></button>
-          )}
-        />
-
-        <div className='scrollable'>
-          {trends && trends.map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
-        </div>
-      </Column>
-    );
-  }
-
-}
diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js
index 0e9592c977fdefc26021b11c153166a252f275de..b128e67d23d02b0258000081ac06b44db8e9c7d3 100644
--- a/app/javascript/mastodon/features/ui/components/boost_modal.js
+++ b/app/javascript/mastodon/features/ui/components/boost_modal.js
@@ -13,8 +13,8 @@ const messages = defineMessages({
   reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
 });
 
-@injectIntl
-export default class BoostModal extends ImmutablePureComponent {
+export default @injectIntl
+class BoostModal extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -37,7 +37,7 @@ export default class BoostModal extends ImmutablePureComponent {
   }
 
   handleAccountClick = (e) => {
-    if (e.button === 0) {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
       e.preventDefault();
       this.props.onClose();
       this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js
index 3ab867b5a714fc55a1accc44b00c96e7ba769318..b7e350cbce29175a8e4e578be958364a05574985 100644
--- a/app/javascript/mastodon/features/ui/components/columns_area.js
+++ b/app/javascript/mastodon/features/ui/components/columns_area.js
@@ -1,6 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { injectIntl } from 'react-intl';
+import { defineMessages, injectIntl } from 'react-intl';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
@@ -29,10 +29,14 @@ const componentMap = {
   'LIST': ListTimeline,
 };
 
-const shouldHideFAB = path => path.match(/^\/statuses\//);
+const messages = defineMessages({
+  publish: { id: 'compose_form.publish', defaultMessage: 'Toot' },
+});
 
-@component => injectIntl(component, { withRef: true })
-export default class ColumnsArea extends ImmutablePureComponent {
+const shouldHideFAB = path => path.match(/^\/statuses\/|^\/search|^\/getting-started/);
+
+export default @(component => injectIntl(component, { withRef: true }))
+class ColumnsArea extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object.isRequired,
@@ -149,14 +153,14 @@ export default class ColumnsArea extends ImmutablePureComponent {
   }
 
   render () {
-    const { columns, children, singleColumn, isModalOpen } = this.props;
+    const { columns, children, singleColumn, isModalOpen, intl } = this.props;
     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'><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)}><i className='fa fa-pencil' /></Link>;
 
       return columnIndex !== -1 ? [
         <ReactSwipeableViews key='content' index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }}>
diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modal.js b/app/javascript/mastodon/features/ui/components/confirmation_modal.js
index 86588c46a23ed869f425d1bb02ba76b1251864ca..f0f3ad134d22e8f7b29e81b46ac362c6ee97fb7f 100644
--- a/app/javascript/mastodon/features/ui/components/confirmation_modal.js
+++ b/app/javascript/mastodon/features/ui/components/confirmation_modal.js
@@ -3,8 +3,8 @@ import PropTypes from 'prop-types';
 import { injectIntl, FormattedMessage } from 'react-intl';
 import Button from '../../../components/button';
 
-@injectIntl
-export default class ConfirmationModal extends React.PureComponent {
+export default @injectIntl
+class ConfirmationModal extends React.PureComponent {
 
   static propTypes = {
     message: PropTypes.node.isRequired,
diff --git a/app/javascript/mastodon/features/ui/components/embed_modal.js b/app/javascript/mastodon/features/ui/components/embed_modal.js
index 52aab00d0b698949f513e510a2d6a946ed063d70..982781db073d69319032ed809f6b01089e784c52 100644
--- a/app/javascript/mastodon/features/ui/components/embed_modal.js
+++ b/app/javascript/mastodon/features/ui/components/embed_modal.js
@@ -4,8 +4,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import { FormattedMessage, injectIntl } from 'react-intl';
 import api from '../../../api';
 
-@injectIntl
-export default class EmbedModal extends ImmutablePureComponent {
+export default @injectIntl
+class EmbedModal extends ImmutablePureComponent {
 
   static propTypes = {
     url: PropTypes.string.isRequired,
@@ -77,6 +77,7 @@ export default class EmbedModal extends ImmutablePureComponent {
             className='embed-modal__iframe'
             frameBorder='0'
             ref={this.setIframeRef}
+            sandbox='allow-same-origin'
             title='preview'
           />
         </div>
diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
index 21bf6d81b6db239559d9b0c1f059ed6caf38fd24..7488a3598bc143608c9985b7b4329fc600b07187 100644
--- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js
+++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
@@ -19,8 +19,8 @@ const mapDispatchToProps = (dispatch, { id }) => ({
 
 });
 
-@connect(mapStateToProps, mapDispatchToProps)
-export default class FocalPointModal extends ImmutablePureComponent {
+export default @connect(mapStateToProps, mapDispatchToProps)
+class FocalPointModal extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.js
index c7360a7264755a07ce95d73a5bb47289eee2de5c..5e1cf75af79aad303c4a5be2edcd239c97b77de5 100644
--- a/app/javascript/mastodon/features/ui/components/image_loader.js
+++ b/app/javascript/mastodon/features/ui/components/image_loader.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
+import { LoadingBar } from 'react-redux-loading-bar';
 import ZoomableImage from './zoomable_image';
 
 export default class ImageLoader extends React.PureComponent {
@@ -23,6 +24,7 @@ export default class ImageLoader extends React.PureComponent {
   state = {
     loading: true,
     error: false,
+    width: null,
   }
 
   removers = [];
@@ -122,6 +124,7 @@ export default class ImageLoader extends React.PureComponent {
 
   setCanvasRef = c => {
     this.canvas = c;
+    if (c) this.setState({ width: c.offsetWidth });
   }
 
   render () {
@@ -135,6 +138,7 @@ export default class ImageLoader extends React.PureComponent {
 
     return (
       <div className={className}>
+        <LoadingBar loading={loading ? 1 : 0} className='loading-bar' style={{ width: this.state.width || width }} />
         {loading ? (
           <canvas
             className='image-loader__preview-canvas'
diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js
index 6af0a101c9f17a323e7a934dec2ee4e23300a6e6..d29a4a6a7d3a6a19319dd3bf102830216eb8f04c 100644
--- a/app/javascript/mastodon/features/ui/components/media_modal.js
+++ b/app/javascript/mastodon/features/ui/components/media_modal.js
@@ -16,10 +16,10 @@ const messages = defineMessages({
   next: { id: 'lightbox.next', defaultMessage: 'Next' },
 });
 
-const previewState = 'previewMediaModal';
+export const previewState = 'previewMediaModal';
 
-@injectIntl
-export default class MediaModal extends ImmutablePureComponent {
+export default @injectIntl
+class MediaModal extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.list.isRequired,
@@ -54,19 +54,23 @@ export default class MediaModal extends ImmutablePureComponent {
     this.setState({ index: index % this.props.media.size });
   }
 
-  handleKeyUp = (e) => {
+  handleKeyDown = (e) => {
     switch(e.key) {
     case 'ArrowLeft':
       this.handlePrevClick();
+      e.preventDefault();
+      e.stopPropagation();
       break;
     case 'ArrowRight':
       this.handleNextClick();
+      e.preventDefault();
+      e.stopPropagation();
       break;
     }
   }
 
   componentDidMount () {
-    window.addEventListener('keyup', this.handleKeyUp, false);
+    window.addEventListener('keydown', this.handleKeyDown, false);
     if (this.context.router) {
       const history = this.context.router.history;
       history.push(history.location.pathname, previewState);
@@ -77,7 +81,7 @@ export default class MediaModal extends ImmutablePureComponent {
   }
 
   componentWillUnmount () {
-    window.removeEventListener('keyup', this.handleKeyUp);
+    window.removeEventListener('keydown', this.handleKeyDown);
     if (this.context.router) {
       this.unlistenHistory();
 
@@ -145,7 +149,7 @@ export default class MediaModal extends ImmutablePureComponent {
             startTime={time || 0}
             onCloseVideo={onClose}
             detailed
-            description={image.get('description')}
+            alt={image.get('description')}
             key={image.get('url')}
           />
         );
diff --git a/app/javascript/mastodon/features/ui/components/modal_root.js b/app/javascript/mastodon/features/ui/components/modal_root.js
index a334318ce56422f05e50b8444b6c1c39f3b8b3d3..cc2ab6c8ce9c34c89cc6744b0d94619e0de8afff 100644
--- a/app/javascript/mastodon/features/ui/components/modal_root.js
+++ b/app/javascript/mastodon/features/ui/components/modal_root.js
@@ -11,16 +11,15 @@ import BoostModal from './boost_modal';
 import ConfirmationModal from './confirmation_modal';
 import FocalPointModal from './focal_point_modal';
 import {
-  OnboardingModal,
   MuteModal,
   ReportModal,
   EmbedModal,
   ListEditor,
+  ListAdder,
 } from '../../../features/ui/util/async-components';
 
 const MODAL_COMPONENTS = {
   'MEDIA': () => Promise.resolve({ default: MediaModal }),
-  'ONBOARDING': OnboardingModal,
   'VIDEO': () => Promise.resolve({ default: VideoModal }),
   'BOOST': () => Promise.resolve({ default: BoostModal }),
   'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
@@ -30,6 +29,7 @@ const MODAL_COMPONENTS = {
   'EMBED': EmbedModal,
   'LIST_EDITOR': ListEditor,
   'FOCAL_POINT': () => Promise.resolve({ default: FocalPointModal }),
+  'LIST_ADDER':ListAdder,
 };
 
 export default class ModalRoot extends React.PureComponent {
@@ -41,14 +41,15 @@ export default class ModalRoot extends React.PureComponent {
   };
 
   getSnapshotBeforeUpdate () {
-    const visible = !!this.props.type;
-    return {
-      overflowY: visible ? 'hidden' : null,
-    };
+    return { visible: !!this.props.type };
   }
 
-  componentDidUpdate (prevProps, prevState, { overflowY }) {
-    document.body.style.overflowY = overflowY;
+  componentDidUpdate (prevProps, prevState, { visible }) {
+    if (visible) {
+      document.body.classList.add('with-modals--active');
+    } else {
+      document.body.classList.remove('with-modals--active');
+    }
   }
 
   renderLoading = modalId => () => {
diff --git a/app/javascript/mastodon/features/ui/components/mute_modal.js b/app/javascript/mastodon/features/ui/components/mute_modal.js
index 73e48cf09b18ca1c8a49c688cdcf7b8a8fc6c7a5..ac356b42a7b26f19c0e90428debbd38a0567c7b5 100644
--- a/app/javascript/mastodon/features/ui/components/mute_modal.js
+++ b/app/javascript/mastodon/features/ui/components/mute_modal.js
@@ -33,9 +33,9 @@ const mapDispatchToProps = dispatch => {
   };
 };
 
-@connect(mapStateToProps, mapDispatchToProps)
+export default @connect(mapStateToProps, mapDispatchToProps)
 @injectIntl
-export default class MuteModal extends React.PureComponent {
+class MuteModal extends React.PureComponent {
 
   static propTypes = {
     isSubmitting: PropTypes.bool.isRequired,
diff --git a/app/javascript/mastodon/features/ui/components/onboarding_modal.js b/app/javascript/mastodon/features/ui/components/onboarding_modal.js
deleted file mode 100644
index 9b713cf9ee595116a206cd5457f16255c236048d..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/features/ui/components/onboarding_modal.js
+++ /dev/null
@@ -1,324 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import PropTypes from 'prop-types';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import ReactSwipeableViews from 'react-swipeable-views';
-import classNames from 'classnames';
-import Permalink from '../../../components/permalink';
-import ComposeForm from '../../compose/components/compose_form';
-import Search from '../../compose/components/search';
-import NavigationBar from '../../compose/components/navigation_bar';
-import ColumnHeader from './column_header';
-import { List as ImmutableList } from 'immutable';
-import { me } from '../../../initial_state';
-
-const noop = () => { };
-
-const messages = defineMessages({
-  home_title: { id: 'column.home', defaultMessage: 'Home' },
-  notifications_title: { id: 'column.notifications', defaultMessage: 'Notifications' },
-  local_title: { id: 'column.community', defaultMessage: 'Local timeline' },
-  federated_title: { id: 'column.public', defaultMessage: 'Federated timeline' },
-});
-
-const PageOne = ({ acct, domain }) => (
-  <div className='onboarding-modal__page onboarding-modal__page-one'>
-    <div className='onboarding-modal__page-one__lead'>
-      <h1><FormattedMessage id='onboarding.page_one.welcome' defaultMessage='Welcome to Mastodon!' /></h1>
-      <p><FormattedMessage id='onboarding.page_one.federation' defaultMessage='Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.' /></p>
-    </div>
-
-    <div className='onboarding-modal__page-one__extra'>
-      <div className='display-case'>
-        <div className='display-case__label'>
-          <FormattedMessage id='onboarding.page_one.full_handle' defaultMessage='Your full handle' />
-        </div>
-
-        <div className='display-case__case'>
-          @{acct}@{domain}
-        </div>
-      </div>
-
-      <p><FormattedMessage id='onboarding.page_one.handle_hint' defaultMessage='This is what you would tell your friends to search for.' /></p>
-    </div>
-  </div>
-);
-
-PageOne.propTypes = {
-  acct: PropTypes.string.isRequired,
-  domain: PropTypes.string.isRequired,
-};
-
-const PageTwo = ({ myAccount }) => (
-  <div className='onboarding-modal__page onboarding-modal__page-two'>
-    <div className='figure non-interactive'>
-      <div className='pseudo-drawer'>
-        <NavigationBar account={myAccount} />
-
-        <ComposeForm
-          text='Awoo! #introductions'
-          suggestions={ImmutableList()}
-          mentionedDomains={[]}
-          spoiler={false}
-          onChange={noop}
-          onSubmit={noop}
-          onPaste={noop}
-          onPickEmoji={noop}
-          onChangeSpoilerText={noop}
-          onClearSuggestions={noop}
-          onFetchSuggestions={noop}
-          onSuggestionSelected={noop}
-          showSearch
-        />
-      </div>
-    </div>
-
-    <p><FormattedMessage id='onboarding.page_two.compose' defaultMessage='Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.' /></p>
-  </div>
-);
-
-PageTwo.propTypes = {
-  myAccount: ImmutablePropTypes.map.isRequired,
-};
-
-const PageThree = ({ myAccount }) => (
-  <div className='onboarding-modal__page onboarding-modal__page-three'>
-    <div className='figure non-interactive'>
-      <Search
-        value=''
-        onChange={noop}
-        onSubmit={noop}
-        onClear={noop}
-        onShow={noop}
-      />
-
-      <div className='pseudo-drawer'>
-        <NavigationBar account={myAccount} />
-      </div>
-    </div>
-
-    <p><FormattedMessage id='onboarding.page_three.search' defaultMessage='Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.' values={{ illustration: <Permalink to='/timelines/tag/illustration' href='/tags/illustration'>#illustration</Permalink>, introductions: <Permalink to='/timelines/tag/introductions' href='/tags/introductions'>#introductions</Permalink> }} /></p>
-    <p><FormattedMessage id='onboarding.page_three.profile' defaultMessage='Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.' /></p>
-  </div>
-);
-
-PageThree.propTypes = {
-  myAccount: ImmutablePropTypes.map.isRequired,
-};
-
-const PageFour = ({ domain, intl }) => (
-  <div className='onboarding-modal__page onboarding-modal__page-four'>
-    <div className='onboarding-modal__page-four__columns'>
-      <div className='row'>
-        <div>
-          <div className='figure non-interactive'><ColumnHeader icon='home' type={intl.formatMessage(messages.home_title)} /></div>
-          <p><FormattedMessage id='onboarding.page_four.home' defaultMessage='The home timeline shows posts from people you follow.' /></p>
-        </div>
-
-        <div>
-          <div className='figure non-interactive'><ColumnHeader icon='bell' type={intl.formatMessage(messages.notifications_title)} /></div>
-          <p><FormattedMessage id='onboarding.page_four.notifications' defaultMessage='The notifications column shows when someone interacts with you.' /></p>
-        </div>
-      </div>
-
-      <div className='row'>
-        <div>
-          <div className='figure non-interactive' style={{ marginBottom: 0 }}><ColumnHeader icon='users' type={intl.formatMessage(messages.local_title)} /></div>
-        </div>
-
-        <div>
-          <div className='figure non-interactive' style={{ marginBottom: 0 }}><ColumnHeader icon='globe' type={intl.formatMessage(messages.federated_title)} /></div>
-        </div>
-      </div>
-
-      <p><FormattedMessage id='onboarding.page_five.public_timelines' defaultMessage='The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.' values={{ domain }} /></p>
-    </div>
-  </div>
-);
-
-PageFour.propTypes = {
-  domain: PropTypes.string.isRequired,
-  intl: PropTypes.object.isRequired,
-};
-
-const PageSix = ({ admin, domain }) => {
-  let adminSection = '';
-
-  if (admin) {
-    adminSection = (
-      <p>
-        <FormattedMessage id='onboarding.page_six.admin' defaultMessage="Your instance's admin is {admin}." values={{ admin: <Permalink href={admin.get('url')} to={`/accounts/${admin.get('id')}`}>@{admin.get('acct')}</Permalink> }} />
-        <br />
-        <FormattedMessage id='onboarding.page_six.read_guidelines' defaultMessage="Please read {domain}'s {guidelines}!" values={{ domain, guidelines: <a href='/about/more' target='_blank'><FormattedMessage id='onboarding.page_six.guidelines' defaultMessage='community guidelines' /></a> }} />
-      </p>
-    );
-  }
-
-  return (
-    <div className='onboarding-modal__page onboarding-modal__page-six'>
-      <h1><FormattedMessage id='onboarding.page_six.almost_done' defaultMessage='Almost done...' /></h1>
-      {adminSection}
-      <p><FormattedMessage id='onboarding.page_six.github' defaultMessage='Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.' values={{ github: <a href='https://github.com/tootsuite/mastodon' target='_blank' rel='noopener'>GitHub</a> }} /></p>
-      <p><FormattedMessage id='onboarding.page_six.apps_available' defaultMessage='There are {apps} available for iOS, Android and other platforms.' values={{ apps: <a href='https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md' target='_blank' rel='noopener'><FormattedMessage id='onboarding.page_six.various_app' defaultMessage='mobile apps' /></a> }} /></p>
-      <p><em><FormattedMessage id='onboarding.page_six.appetoot' defaultMessage='Bon Appetoot!' /></em></p>
-    </div>
-  );
-};
-
-PageSix.propTypes = {
-  admin: ImmutablePropTypes.map,
-  domain: PropTypes.string.isRequired,
-};
-
-const mapStateToProps = state => ({
-  myAccount: state.getIn(['accounts', me]),
-  admin: state.getIn(['accounts', state.getIn(['meta', 'admin'])]),
-  domain: state.getIn(['meta', 'domain']),
-});
-
-@connect(mapStateToProps)
-@injectIntl
-export default class OnboardingModal extends React.PureComponent {
-
-  static propTypes = {
-    onClose: PropTypes.func.isRequired,
-    intl: PropTypes.object.isRequired,
-    myAccount: ImmutablePropTypes.map.isRequired,
-    domain: PropTypes.string.isRequired,
-    admin: ImmutablePropTypes.map,
-  };
-
-  state = {
-    currentIndex: 0,
-  };
-
-  componentWillMount() {
-    const { myAccount, admin, domain, intl } = this.props;
-    this.pages = [
-      <PageOne acct={myAccount.get('acct')} domain={domain} />,
-      <PageTwo myAccount={myAccount} />,
-      <PageThree myAccount={myAccount} />,
-      <PageFour domain={domain} intl={intl} />,
-      <PageSix admin={admin} domain={domain} />,
-    ];
-  };
-
-  componentDidMount() {
-    window.addEventListener('keyup', this.handleKeyUp);
-  }
-
-  componentWillUnmount() {
-    window.addEventListener('keyup', this.handleKeyUp);
-  }
-
-  handleSkip = (e) => {
-    e.preventDefault();
-    this.props.onClose();
-  }
-
-  handleDot = (e) => {
-    const i = Number(e.currentTarget.getAttribute('data-index'));
-    e.preventDefault();
-    this.setState({ currentIndex: i });
-  }
-
-  handlePrev = () => {
-    this.setState(({ currentIndex }) => ({
-      currentIndex: Math.max(0, currentIndex - 1),
-    }));
-  }
-
-  handleNext = () => {
-    const { pages } = this;
-    this.setState(({ currentIndex }) => ({
-      currentIndex: Math.min(currentIndex + 1, pages.length - 1),
-    }));
-  }
-
-  handleSwipe = (index) => {
-    this.setState({ currentIndex: index });
-  }
-
-  handleKeyUp = ({ key }) => {
-    switch (key) {
-    case 'ArrowLeft':
-      this.handlePrev();
-      break;
-    case 'ArrowRight':
-      this.handleNext();
-      break;
-    }
-  }
-
-  handleClose = () => {
-    this.props.onClose();
-  }
-
-  render () {
-    const { pages } = this;
-    const { currentIndex } = this.state;
-    const hasMore = currentIndex < pages.length - 1;
-
-    const nextOrDoneBtn = hasMore ? (
-      <button onClick={this.handleNext} className='onboarding-modal__nav onboarding-modal__next shake-bottom'>
-        <FormattedMessage id='onboarding.next' defaultMessage='Next' /> <i className='fa fa-fw fa-chevron-right' />
-      </button>
-    ) : (
-      <button onClick={this.handleClose} className='onboarding-modal__nav onboarding-modal__done shake-bottom'>
-        <FormattedMessage id='onboarding.done' defaultMessage='Done' /> <i className='fa fa-fw fa-check' />
-      </button>
-    );
-
-    return (
-      <div className='modal-root__modal onboarding-modal'>
-        <ReactSwipeableViews index={currentIndex} onChangeIndex={this.handleSwipe} className='onboarding-modal__pager'>
-          {pages.map((page, i) => {
-            const className = classNames('onboarding-modal__page__wrapper', `onboarding-modal__page__wrapper-${i}`, {
-              'onboarding-modal__page__wrapper--active': i === currentIndex,
-            });
-
-            return (
-              <div key={i} className={className}>{page}</div>
-            );
-          })}
-        </ReactSwipeableViews>
-
-        <div className='onboarding-modal__paginator'>
-          <div>
-            <button
-              onClick={this.handleSkip}
-              className='onboarding-modal__nav onboarding-modal__skip'
-            >
-              <FormattedMessage id='onboarding.skip' defaultMessage='Skip' />
-            </button>
-          </div>
-
-          <div className='onboarding-modal__dots'>
-            {pages.map((_, i) => {
-              const className = classNames('onboarding-modal__dot', {
-                active: i === currentIndex,
-              });
-
-              return (
-                <div
-                  key={`dot-${i}`}
-                  role='button'
-                  tabIndex='0'
-                  data-index={i}
-                  onClick={this.handleDot}
-                  className={className}
-                />
-              );
-            })}
-          </div>
-
-          <div>
-            {nextOrDoneBtn}
-          </div>
-        </div>
-      </div>
-    );
-  }
-
-}
diff --git a/app/javascript/mastodon/features/ui/components/report_modal.js b/app/javascript/mastodon/features/ui/components/report_modal.js
index 90f0013197060e5af37ccfb0d3d6a745d8144147..bc6b18664a97401baf319872bdced75cc3627b47 100644
--- a/app/javascript/mastodon/features/ui/components/report_modal.js
+++ b/app/javascript/mastodon/features/ui/components/report_modal.js
@@ -37,9 +37,9 @@ const makeMapStateToProps = () => {
   return mapStateToProps;
 };
 
-@connect(makeMapStateToProps)
+export default @connect(makeMapStateToProps)
 @injectIntl
-export default class ReportModal extends ImmutablePureComponent {
+class ReportModal extends ImmutablePureComponent {
 
   static propTypes = {
     isSubmitting: PropTypes.bool,
@@ -106,6 +106,7 @@ export default class ReportModal extends ImmutablePureComponent {
               onChange={this.handleCommentChange}
               onKeyDown={this.handleKeyDown}
               disabled={isSubmitting}
+              autoFocus
             />
 
             {domain && (
diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js
index 60bc56eef31092de8d97986870c4658a436648aa..16236ea51e5e2c6b4e95acb6e97ee328e51339ea 100644
--- a/app/javascript/mastodon/features/ui/components/tabs_bar.js
+++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js
@@ -24,9 +24,9 @@ export function getLink (index) {
   return links[index].props.to;
 }
 
-@injectIntl
+export default @injectIntl
 @withRouter
-export default class TabsBar extends React.PureComponent {
+class TabsBar extends React.PureComponent {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.js
index 9ed4a43ad1fa151942c7463a774c3ccf8d8d5477..7cf3eb4d458f6db79cd19a2e1020e09dce52b811 100644
--- a/app/javascript/mastodon/features/ui/components/video_modal.js
+++ b/app/javascript/mastodon/features/ui/components/video_modal.js
@@ -24,7 +24,7 @@ export default class VideoModal extends ImmutablePureComponent {
             startTime={time}
             onCloseVideo={onClose}
             detailed
-            description={media.get('description')}
+            alt={media.get('description')}
           />
         </div>
       </div>
diff --git a/app/javascript/mastodon/features/ui/components/zoomable_image.js b/app/javascript/mastodon/features/ui/components/zoomable_image.js
index 0a0a4d41a93adfde7e40d27614eb929dc5fb4414..3f6562bc991bdeb45f8fcd44f0bd800317f401c3 100644
--- a/app/javascript/mastodon/features/ui/components/zoomable_image.js
+++ b/app/javascript/mastodon/features/ui/components/zoomable_image.js
@@ -137,6 +137,7 @@ export default class ZoomableImage extends React.PureComponent {
           role='presentation'
           ref={this.setImageRef}
           alt={alt}
+          title={alt}
           src={src}
           style={{
             transform: `scale(${scale})`,
diff --git a/app/javascript/mastodon/features/ui/containers/columns_area_container.js b/app/javascript/mastodon/features/ui/containers/columns_area_container.js
index f3e82a8ac27aaa6297c1f834374d089f6b4d707f..42b9e48247df4d26792a8f773242b19bd3d76af6 100644
--- a/app/javascript/mastodon/features/ui/containers/columns_area_container.js
+++ b/app/javascript/mastodon/features/ui/containers/columns_area_container.js
@@ -6,4 +6,4 @@ const mapStateToProps = state => ({
   isModalOpen: !!state.get('modal').modalType,
 });
 
-export default connect(mapStateToProps, null, null, { withRef: true })(ColumnsArea);
+export default connect(mapStateToProps, null, null, { forwardRef: true })(ColumnsArea);
diff --git a/app/javascript/mastodon/features/ui/containers/loading_bar_container.js b/app/javascript/mastodon/features/ui/containers/loading_bar_container.js
index 4bb90fb689f5ba64ab81b123f4ef64ba332d6e69..63e994f927c2215236d2884afa2e6a3cf7e17512 100644
--- a/app/javascript/mastodon/features/ui/containers/loading_bar_container.js
+++ b/app/javascript/mastodon/features/ui/containers/loading_bar_container.js
@@ -1,8 +1,8 @@
 import { connect }    from 'react-redux';
 import LoadingBar from 'react-redux-loading-bar';
 
-const mapStateToProps = (state) => ({
-  loading: state.get('loadingBar'),
+const mapStateToProps = (state, ownProps) => ({
+  loading: state.get('loadingBar')[ownProps.scope || 'default'],
 });
 
 export default connect(mapStateToProps)(LoadingBar.WrappedComponent);
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index 56a85623032c5c178e53a4157e0c18035077e2e5..f01c2bf247861d4d3676303a238271f7d0c7aec0 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -1,12 +1,14 @@
 import classNames from 'classnames';
 import React from 'react';
-import NotificationsContainer from './containers/notifications_container';
+import { HotKeys } from 'react-hotkeys';
+import { defineMessages, injectIntl } from 'react-intl';
+import { connect } from 'react-redux';
+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 { connect } from 'react-redux';
-import { Redirect, withRouter } from 'react-router-dom';
 import { isMobile } from '../../is_mobile';
 import { debounce } from 'lodash';
 import { uploadCompose, resetCompose } from '../../actions/compose';
@@ -44,9 +46,8 @@ import {
   PinnedStatuses,
   Lists,
 } from './util/async-components';
-import { HotKeys } from 'react-hotkeys';
 import { me } from '../../initial_state';
-import { defineMessages, injectIntl } from 'react-intl';
+import { previewState } from './components/media_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.
@@ -58,7 +59,8 @@ const messages = defineMessages({
 
 const mapStateToProps = state => ({
   isComposing: state.getIn(['compose', 'is_composing']),
-  hasComposingText: state.getIn(['compose', 'text']) !== '',
+  hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0,
+  hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0,
   dropdownMenuIsOpen: state.getIn(['dropdown_menu', 'openId']) !== null,
 });
 
@@ -88,6 +90,7 @@ const keyMap = {
   goToProfile: 'g u',
   goToBlocked: 'g b',
   goToMuted: 'g m',
+  goToRequests: 'g r',
   toggleHidden: 'x',
 };
 
@@ -117,6 +120,10 @@ class SwitchingColumnsArea extends React.PureComponent {
     window.removeEventListener('resize', this.handleResize);
   }
 
+  shouldUpdateScroll (_, { location }) {
+    return location.state !== previewState;
+  }
+
   handleResize = debounce(() => {
     // The cached heights are no longer accurate, invalidate
     this.props.onLayoutChange();
@@ -127,7 +134,7 @@ class SwitchingColumnsArea extends React.PureComponent {
   });
 
   setRef = c => {
-    this.node = c.getWrappedInstance().getWrappedInstance();
+    this.node = c.getWrappedInstance();
   }
 
   render () {
@@ -141,37 +148,35 @@ class SwitchingColumnsArea extends React.PureComponent {
           {redirect}
           <WrappedRoute path='/getting-started' component={GettingStarted} content={children} />
           <WrappedRoute path='/keyboard-shortcuts' component={KeyboardShortcuts} content={children} />
-          <WrappedRoute path='/timelines/home' component={HomeTimeline} content={children} />
-          <WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} />
-          <WrappedRoute path='/timelines/public/media' component={PublicTimeline} content={children} componentParams={{ onlyMedia: true }} />
-          <WrappedRoute path='/timelines/public/local' exact component={CommunityTimeline} content={children} />
-          <WrappedRoute path='/timelines/public/local/media' component={CommunityTimeline} content={children} componentParams={{ onlyMedia: true }} />
-          <WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} />
-          <WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} />
-          <WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} />
-
-          <WrappedRoute path='/notifications' component={Notifications} content={children} />
-          <WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} />
-          <WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
+          <WrappedRoute path='/timelines/home' component={HomeTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/timelines/public/local' exact component={CommunityTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+
+          <WrappedRoute path='/notifications' component={Notifications} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <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='/statuses/new' component={Compose} content={children} />
-          <WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} />
-          <WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} />
-          <WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} />
-
-          <WrappedRoute path='/accounts/:accountId' exact component={AccountTimeline} content={children} />
-          <WrappedRoute path='/accounts/:accountId/with_replies' component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
-          <WrappedRoute path='/accounts/:accountId/followers' component={Followers} content={children} />
-          <WrappedRoute path='/accounts/:accountId/following' component={Following} content={children} />
-          <WrappedRoute path='/accounts/:accountId/media' component={AccountGallery} content={children} />
-
-          <WrappedRoute path='/follow_requests' component={FollowRequests} content={children} />
-          <WrappedRoute path='/blocks' component={Blocks} content={children} />
-          <WrappedRoute path='/domain_blocks' component={DomainBlocks} content={children} />
-          <WrappedRoute path='/mutes' component={Mutes} content={children} />
-          <WrappedRoute path='/lists' component={Lists} content={children} />
+          <WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+
+          <WrappedRoute path='/accounts/:accountId' exact component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/accounts/:accountId/with_replies' component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll, withReplies: true }} />
+          <WrappedRoute path='/accounts/:accountId/followers' component={Followers} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/accounts/:accountId/following' component={Following} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/accounts/:accountId/media' component={AccountGallery} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+
+          <WrappedRoute path='/follow_requests' component={FollowRequests} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/blocks' component={Blocks} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/domain_blocks' component={DomainBlocks} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/mutes' component={Mutes} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+          <WrappedRoute path='/lists' component={Lists} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
 
           <WrappedRoute component={GenericNotFound} content={children} />
         </WrappedSwitch>
@@ -181,10 +186,10 @@ class SwitchingColumnsArea extends React.PureComponent {
 
 }
 
-@connect(mapStateToProps)
+export default @connect(mapStateToProps)
 @injectIntl
 @withRouter
-export default class UI extends React.PureComponent {
+class UI extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object.isRequired,
@@ -195,6 +200,7 @@ export default class UI extends React.PureComponent {
     children: PropTypes.node,
     isComposing: PropTypes.bool,
     hasComposingText: PropTypes.bool,
+    hasMediaAttachments: PropTypes.bool,
     location: PropTypes.object,
     intl: PropTypes.object.isRequired,
     dropdownMenuIsOpen: PropTypes.bool,
@@ -205,9 +211,9 @@ export default class UI extends React.PureComponent {
   };
 
   handleBeforeUnload = (e) => {
-    const { intl, isComposing, hasComposingText } = this.props;
+    const { intl, isComposing, hasComposingText, hasMediaAttachments } = this.props;
 
-    if (isComposing && hasComposingText) {
+    if (isComposing && (hasComposingText || hasMediaAttachments)) {
       // Setting returnValue to any string causes confirmation dialog.
       // Many browsers no longer display this text to users,
       // but we set user-friendly message for other browsers, e.g. Edge.
@@ -237,6 +243,7 @@ export default class UI extends React.PureComponent {
   }
 
   handleDragOver = (e) => {
+    if (this.dataTransferIsText(e.dataTransfer)) return false;
     e.preventDefault();
     e.stopPropagation();
 
@@ -250,9 +257,11 @@ export default class UI extends React.PureComponent {
   }
 
   handleDrop = (e) => {
+    if (this.dataTransferIsText(e.dataTransfer)) return;
     e.preventDefault();
 
     this.setState({ draggingOver: false });
+    this.dragTargets = [];
 
     if (e.dataTransfer && e.dataTransfer.files.length === 1) {
       this.props.dispatch(uploadCompose(e.dataTransfer.files));
@@ -272,6 +281,10 @@ export default class UI extends React.PureComponent {
     this.setState({ draggingOver: false });
   }
 
+  dataTransferIsText = (dataTransfer) => {
+    return (dataTransfer && Array.from(dataTransfer.types).includes('text/plain') && dataTransfer.items.length === 1);
+  }
+
   closeUploadModal = () => {
     this.setState({ draggingOver: false });
   }
@@ -286,6 +299,7 @@ export default class UI extends React.PureComponent {
 
   componentWillMount () {
     window.addEventListener('beforeunload', this.handleBeforeUnload, false);
+
     document.addEventListener('dragenter', this.handleDragEnter, false);
     document.addEventListener('dragover', this.handleDragOver, false);
     document.addEventListener('drop', this.handleDrop, false);
@@ -296,8 +310,13 @@ export default class UI extends React.PureComponent {
       navigator.serviceWorker.addEventListener('message', this.handleServiceWorkerPostMessage);
     }
 
+    if (typeof window.Notification !== 'undefined' && Notification.permission === 'default') {
+      window.setTimeout(() => Notification.requestPermission(), 120 * 1000);
+    }
+
     this.props.dispatch(expandHomeTimeline());
     this.props.dispatch(expandNotifications());
+
     setTimeout(() => this.props.dispatch(fetchFilters()), 500);
   }
 
@@ -422,6 +441,10 @@ export default class UI extends React.PureComponent {
     this.context.router.history.push('/mutes');
   }
 
+  handleHotkeyGoToRequests = () => {
+    this.context.router.history.push('/follow_requests');
+  }
+
   render () {
     const { draggingOver } = this.state;
     const { children, isComposing, location, dropdownMenuIsOpen } = this.props;
@@ -444,10 +467,11 @@ export default class UI extends React.PureComponent {
       goToProfile: this.handleHotkeyGoToProfile,
       goToBlocked: this.handleHotkeyGoToBlocked,
       goToMuted: this.handleHotkeyGoToMuted,
+      goToRequests: this.handleHotkeyGoToRequests,
     };
 
     return (
-      <HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef}>
+      <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 />
 
diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js
index 8cf2a6e7d79bccae6e15f29628f811efb898ef8f..235fd2a073c2556571a3586358024344e2c57ecd 100644
--- a/app/javascript/mastodon/features/ui/util/async-components.js
+++ b/app/javascript/mastodon/features/ui/util/async-components.js
@@ -102,10 +102,6 @@ export function Mutes () {
   return import(/* webpackChunkName: "features/mutes" */'../../mutes');
 }
 
-export function OnboardingModal () {
-  return import(/* webpackChunkName: "modals/onboarding_modal" */'../components/onboarding_modal');
-}
-
 export function MuteModal () {
   return import(/* webpackChunkName: "modals/mute_modal" */'../components/mute_modal');
 }
@@ -129,3 +125,7 @@ export function EmbedModal () {
 export function ListEditor () {
   return import(/* webpackChunkName: "features/list_editor" */'../../list_editor');
 }
+
+export function ListAdder () {
+  return import(/*webpackChunkName: "features/list_adder" */'../../list_adder');
+}
diff --git a/app/javascript/mastodon/features/ui/util/react_router_helpers.js b/app/javascript/mastodon/features/ui/util/react_router_helpers.js
index 32dfe320b9dba12f0d1ca492033e4a79d6b53adf..d452b871f78ecffbd3720553aca6f3c66af43f9e 100644
--- a/app/javascript/mastodon/features/ui/util/react_router_helpers.js
+++ b/app/javascript/mastodon/features/ui/util/react_router_helpers.js
@@ -26,7 +26,7 @@ WrappedSwitch.propTypes = {
   children: PropTypes.node,
 };
 
-// Small Wraper to extract the params from the route and pass
+// Small Wrapper to extract the params from the route and pass
 // them to the rendered component, together with the content to
 // be rendered inside (the children)
 export class WrappedRoute extends React.Component {
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index 47a165e1698c26c8a08183113e14392ebce5da29..3650fddb630e6d2dbcffad22b48a16b42c1b5307 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -5,7 +5,7 @@ import { fromJS } from 'immutable';
 import { throttle } from 'lodash';
 import classNames from 'classnames';
 import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
-import { displaySensitiveMedia } from '../../initial_state';
+import { displayMedia } from '../../initial_state';
 
 const messages = defineMessages({
   play: { id: 'video.play', defaultMessage: 'Play' },
@@ -84,8 +84,8 @@ export const getPointerPosition = (el, event) => {
   return position;
 };
 
-@injectIntl
-export default class Video extends React.PureComponent {
+export default @injectIntl
+class Video extends React.PureComponent {
 
   static propTypes = {
     preview: PropTypes.string,
@@ -105,15 +105,25 @@ export default class Video extends React.PureComponent {
   state = {
     currentTime: 0,
     duration: 0,
+    volume: 0.5,
     paused: true,
     dragging: false,
     containerWidth: false,
     fullscreen: false,
     hovered: false,
     muted: false,
-    revealed: !this.props.sensitive || displaySensitiveMedia,
+    revealed: displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all',
   };
 
+  // hard coded in components.scss
+  // any way to get ::before values programatically?
+  volWidth = 50;
+  volOffset = 70;
+  volHandleOffset = v => {
+    const offset = v * this.volWidth + this.volOffset;
+    return (offset > 110) ? 110 : offset;
+  }
+
   setPlayerRef = c => {
     this.player = c;
 
@@ -132,6 +142,10 @@ export default class Video extends React.PureComponent {
     this.seek = c;
   }
 
+  setVolumeRef = c => {
+    this.volume = c;
+  }
+
   handleClickRoot = e => e.stopPropagation();
 
   handlePlay = () => {
@@ -149,6 +163,43 @@ export default 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);
+    document.addEventListener('touchend', this.handleVolumeMouseUp, true);
+
+    this.handleMouseVolSlide(e);
+
+    e.preventDefault();
+    e.stopPropagation();
+  }
+
+  handleVolumeMouseUp = () => {
+    document.removeEventListener('mousemove', this.handleMouseVolSlide, true);
+    document.removeEventListener('mouseup', this.handleVolumeMouseUp, true);
+    document.removeEventListener('touchmove', this.handleMouseVolSlide, true);
+    document.removeEventListener('touchend', this.handleVolumeMouseUp, true);
+  }
+
+  handleMouseVolSlide = throttle(e => {
+
+    const rect = this.volume.getBoundingClientRect();
+    const x = (e.clientX - rect.left) / this.volWidth; //x position within the element.
+
+    if(!isNaN(x)) {
+      var slideamt = x;
+      if(x > 1) {
+        slideamt = 1;
+      } else if(x < 0) {
+        slideamt = 0;
+      }
+      this.video.volume = slideamt;
+      this.setState({ volume: slideamt });
+    }
+  }, 60);
+
   handleMouseDown = e => {
     document.addEventListener('mousemove', this.handleMouseMove, true);
     document.addEventListener('mouseup', this.handleMouseUp, true);
@@ -158,6 +209,9 @@ export default class Video extends React.PureComponent {
     this.setState({ dragging: true });
     this.video.pause();
     this.handleMouseMove(e);
+
+    e.preventDefault();
+    e.stopPropagation();
   }
 
   handleMouseUp = () => {
@@ -174,8 +228,10 @@ export default class Video extends React.PureComponent {
     const { x } = getPointerPosition(this.seek, e);
     const currentTime = Math.floor(this.video.duration * x);
 
-    this.video.currentTime = currentTime;
-    this.setState({ currentTime });
+    if (!isNaN(currentTime)) {
+      this.video.currentTime = currentTime;
+      this.setState({ currentTime });
+    }
   }, 60);
 
   togglePlay = () => {
@@ -247,11 +303,12 @@ export default class Video extends React.PureComponent {
   }
 
   handleOpenVideo = () => {
-    const { src, preview, width, height } = this.props;
+    const { src, preview, width, height, alt } = this.props;
     const media = fromJS({
       type: 'video',
       url: src,
       preview_url: preview,
+      description: alt,
       width,
       height,
     });
@@ -266,9 +323,12 @@ export default class Video extends React.PureComponent {
   }
 
   render () {
-    const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed } = this.props;
-    const { containerWidth, currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
+    const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed, sensitive } = this.props;
+    const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
     const progress = (currentTime / duration) * 100;
+
+    const volumeWidth = (muted) ? 0 : volume * this.volWidth;
+    const volumeHandleLoc = (muted) ? this.volHandleOffset(0) : this.volHandleOffset(volume);
     const playerStyle = {};
 
     let { width, height } = this.props;
@@ -281,6 +341,22 @@ export default class Video extends React.PureComponent {
       playerStyle.height = height;
     }
 
+    let preload;
+    if (startTime || fullscreen || dragging) {
+      preload = 'auto';
+    } else if (detailed) {
+      preload = 'metadata';
+    } else {
+      preload = 'none';
+    }
+
+    let warning;
+    if (sensitive) {
+      warning = <FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' />;
+    } else {
+      warning = <FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' />;
+    }
+
     return (
       <div
         role='menuitem'
@@ -296,13 +372,15 @@ export default class Video extends React.PureComponent {
           ref={this.setVideoRef}
           src={src}
           poster={preview}
-          preload={startTime ? 'auto' : 'none'}
+          preload={preload}
           loop
           role='button'
           tabIndex='0'
           aria-label={alt}
+          title={alt}
           width={width}
           height={height}
+          volume={volume}
           onClick={this.togglePlay}
           onPlay={this.handlePlay}
           onPause={this.handlePause}
@@ -312,7 +390,7 @@ export default class Video extends React.PureComponent {
         />
 
         <button type='button' className={classNames('video-player__spoiler', { active: !revealed })} onClick={this.toggleReveal}>
-          <span className='video-player__spoiler__title'><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span>
+          <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>
 
@@ -331,9 +409,15 @@ export default 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)} onClick={this.toggleMute}><i className={classNames('fa fa-fw', { 'fa-volume-off': muted, 'fa-volume-up': !muted })} /></button>
-
-              {!onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><i className='fa fa-fw fa-eye' /></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>
+              <div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
+                <div className='video-player__volume__current' style={{ width: `${volumeWidth}px` }} />
+                <span
+                  className={classNames('video-player__volume__handle')}
+                  tabIndex='0'
+                  style={{ left: `${volumeHandleLoc}px` }}
+                />
+              </div>
 
               {(detailed || fullscreen) &&
                 <span>
@@ -345,6 +429,7 @@ export default class Video extends React.PureComponent {
             </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>
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
index 807262fd7b666499b79e0abdac24dc5e7a3ca99d..8c2e9d2de49d9b87428b873196c1aaff74b5e7c5 100644
--- a/app/javascript/mastodon/initial_state.js
+++ b/app/javascript/mastodon/initial_state.js
@@ -5,12 +5,17 @@ const getMeta = (prop) => initialState && initialState.meta && initialState.meta
 
 export const reduceMotion = getMeta('reduce_motion');
 export const autoPlayGif = getMeta('auto_play_gif');
-export const displaySensitiveMedia = getMeta('display_sensitive_media');
+export const displayMedia = getMeta('display_media');
+export const expandSpoilers = getMeta('expand_spoilers');
 export const unfollowModal = getMeta('unfollow_modal');
 export const boostModal = getMeta('boost_modal');
 export const deleteModal = getMeta('delete_modal');
 export const me = getMeta('me');
 export const searchEnabled = getMeta('search_enabled');
 export const invitesEnabled = getMeta('invites_enabled');
+export const version = getMeta('version');
+export const mascot = getMeta('mascot');
+export const profile_directory = getMeta('profile_directory');
+export const isStaff = getMeta('is_staff');
 
 export default initialState;
diff --git a/app/javascript/mastodon/link_header.js b/app/javascript/mastodon/link_header.js
deleted file mode 100644
index a3e7ccf1c1b01633a65bb2d9734ac72594909177..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/link_header.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import Link from 'http-link-header';
-import querystring from 'querystring';
-
-Link.parseAttrs = (link, parts) => {
-  let match = null;
-  let attr  = '';
-  let value = '';
-  let attrs = '';
-
-  let uriAttrs = /<(.*)>;\s*(.*)/gi.exec(parts);
-
-  if(uriAttrs) {
-    attrs = uriAttrs[2];
-    link  = Link.parseParams(link, uriAttrs[1]);
-  }
-
-  while(match = Link.attrPattern.exec(attrs)) { // eslint-disable-line no-cond-assign
-    attr  = match[1].toLowerCase();
-    value = match[4] || match[3] || match[2];
-
-    if( /\*$/.test(attr)) {
-      Link.setAttr(link, attr, Link.parseExtendedValue(value));
-    } else if(/%/.test(value)) {
-      Link.setAttr(link, attr, querystring.decode(value));
-    } else {
-      Link.setAttr(link, attr, value);
-    }
-  }
-
-  return link;
-};
-
-export default Link;
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index ff0ddd95f277ad59644f3eec1ec4bdb6c2468e32..1486272e2264482e438ca409ffea96491a6d3459 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "اضافو أو حذف مِن القوائم",
   "account.badges.bot": "روبوت",
   "account.block": "حظر @{name}",
   "account.block_domain": "إخفاء كل شيئ قادم من إسم النطاق {domain}",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "قد لا تعكس المعلومات أدناه الملف الشخصي الكامل للمستخدم.",
   "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} إنتقل إلى :",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "عرض ترقيات @{name}",
   "account.unblock": "إلغاء الحظر عن @{name}",
   "account.unblock_domain": "فك حظر {domain}",
+  "account.unendorse": "إزالة ترويجه مِن الملف الشخصي",
   "account.unfollow": "إلغاء المتابعة",
   "account.unmute": "إلغاء الكتم عن @{name}",
   "account.unmute_notifications": "إلغاء كتم إخطارات @{name}",
@@ -85,10 +92,12 @@
   "confirmations.mute.confirm": "أكتم",
   "confirmations.mute.message": "هل أنت متأكد أنك تريد كتم {name} ؟",
   "confirmations.redraft.confirm": "إزالة و إعادة الصياغة",
-  "confirmations.redraft.message": "هل أنت متأكد من أنك تريد حذف هذا المنشور و إعادة صياغته ؟ سوف تفقد جميع الردود و الترقيات و المفضلة المتصلة به.",
+  "confirmations.redraft.message": "هل أنت متأكد من أنك تريد حذف هذا المنشور و إعادة صياغته ؟ سوف تفقد جميع الإعجابات و الترقيات أما الردود المتصلة به فستُصبِح يتيمة.",
+  "confirmations.reply.confirm": "رد",
+  "confirmations.reply.message": "الرد في الحين سوف يُعيد كتابة الرسالة التي أنت بصدد كتابتها. متأكد من أنك تريد المواصلة؟",
   "confirmations.unfollow.confirm": "إلغاء المتابعة",
   "confirmations.unfollow.message": "متأكد من أنك تريد إلغاء متابعة {name} ؟",
-  "embed.instructions": "يمكنكم إدماج هذه الحالة على موقعكم الإلكتروني عن طريق نسخ الشفرة أدناه.",
+  "embed.instructions": "يمكنكم إدماج هذا المنشور على موقعكم الإلكتروني عن طريق نسخ الشفرة أدناه.",
   "embed.preview": "هكذا ما سوف يبدو عليه :",
   "emoji_button.activity": "الأنشطة",
   "emoji_button.custom": "مخصص",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "نتائج البحث",
   "emoji_button.symbols": "رموز",
   "emoji_button.travel": "أماكن و أسفار",
+  "empty_column.account_timeline": "ليس هناك تبويقات!",
+  "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} أو استخدم حقل البحث لكي تكتشف مستخدمين آخرين.",
   "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.documentation": "Documentation",
-  "getting_started.find_friends": "البحث عن أصدقاء على تويتر",
+  "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.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",
   "home.column_settings.basic": "أساسية",
   "home.column_settings.show_reblogs": "عرض الترقيات",
   "home.column_settings.show_replies": "عرض الردود",
+  "introduction.federation.action": "التالي",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "كافة المنشورات التي نُشِرت إلى العامة على الخوادم الأخرى للفديفرس سوف يتم عرضها على الخيط المُوحَّد.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "سوف تُعرَض منشورات الأشخاص الذين تُتابِعهم على الخيط الرئيسي. بإمكانك متابعة أي حساب أيا كان الخادم الذي هو عليه!",
+  "introduction.federation.local.headline": "Local",
+  "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": "Description",
+  "keyboard_shortcuts.direct": "لفتح عمود الرسائل المباشرة",
   "keyboard_shortcuts.down": "للإنتقال إلى أسفل القائمة",
   "keyboard_shortcuts.enter": "to open status",
   "keyboard_shortcuts.favourite": "للإضافة إلى المفضلة",
+  "keyboard_shortcuts.favourites": "لفتح قائمة المفضلات",
+  "keyboard_shortcuts.federated": "لفتح الخيط الزمني الفديرالي",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "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": "لإلغاء التركيز على حقل النص أو نافذة البحث",
@@ -159,14 +213,16 @@
   "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": "Muted words",
+  "navigation_bar.filters": "الكلمات المكتومة",
   "navigation_bar.follow_requests": "طلبات المتابعة",
   "navigation_bar.info": "معلومات إضافية",
   "navigation_bar.keyboard_shortcuts": "إختصارات لوحة المفاتيح",
@@ -178,7 +234,7 @@
   "navigation_bar.preferences": "التفضيلات",
   "navigation_bar.public_timeline": "الخيط العام الموحد",
   "navigation_bar.security": "الأمان",
-  "notification.favourite": "{name} أعجب بمنشورك",
+  "notification.favourite": "أُعجِب {name} بمنشورك",
   "notification.follow": "{name} يتابعك",
   "notification.mention": "{name} ذكرك",
   "notification.reblog": "{name} قام بترقية تبويقك",
@@ -186,35 +242,21 @@
   "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.push": "الإخطارات المدفوعة",
-  "notifications.column_settings.push_meta": "هذا الجهاز",
   "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.group": "{count} إشعارات",
-  "onboarding.done": "تم",
-  "onboarding.next": "التالي",
-  "onboarding.page_five.public_timelines": "تُعرَض في الخيط الزمني المحلي المشاركات العامة المحررة من طرف جميع المسجلين في {domain}. أما في الخيط الزمني الموحد ، فإنه يتم عرض جميع المشاركات العامة المنشورة من طرف جميع الأشخاص المتابَعين من طرف أعضاء {domain}. هذه هي الخيوط الزمنية العامة، وهي طريقة رائعة للتعرف أشخاص جدد.",
-  "onboarding.page_four.home": "تعرض الصفحة الرئيسية منشورات جميع الأشخاص الذين تتابعهم.",
-  "onboarding.page_four.notifications": "فعندما يتفاعل شخص ما معك، عمود الإخطارات يخبرك.",
-  "onboarding.page_one.federation": "ماستدون شبكة من خوادم مستقلة متلاحمة تهدف إلى إنشاء أكبر شبكة اجتماعية موحدة. تسمى هذه السرفيرات بمثيلات خوادم.",
-  "onboarding.page_one.full_handle": "عنوانك الكامل",
-  "onboarding.page_one.handle_hint": "هذا هو ما يجب عليك توصيله لأصدقائك للبحث عنه.",
-  "onboarding.page_one.welcome": "مرحبا بك في ماستدون !",
-  "onboarding.page_six.admin": "مدير(ة) مثيل الخادم هذا {admin}.",
-  "onboarding.page_six.almost_done": "أنهيت تقريبا ...",
-  "onboarding.page_six.appetoot": "تمتع بالتبويق !",
-  "onboarding.page_six.apps_available": "هناك {apps} متوفرة لأنظمة آي أو إس و أندرويد و غيرها من المنصات و الأنظمة.",
-  "onboarding.page_six.github": "ماستدون برنامج مفتوح المصدر. يمكنك المساهمة، أو الإبلاغ عن تقارير الأخطاء، على GitHub {github}.",
-  "onboarding.page_six.guidelines": "المبادئ التوجيهية للمجتمع",
-  "onboarding.page_six.read_guidelines": "رجاءا، قم بالإطلاع على {guidelines} لـ {domain} !",
-  "onboarding.page_six.various_app": "تطبيقات الجوال",
-  "onboarding.page_three.profile": "يمكنك إدخال تعديلات على ملفك الشخصي عن طريق تغيير الصورة الرمزية و السيرة و إسمك المستعار. هناك، سوف تجد أيضا تفضيلات أخرى متاحة.",
-  "onboarding.page_three.search": "باستخدام شريط البحث يمكنك العثور على أشخاص و أصدقاء أو الإطلاع على أوسمة، كـ {illustration} و {introductions}. للبحث عن شخص غير مسجل في مثيل الخادم هذا، استخدم مُعرّفه الكامل.",
-  "onboarding.page_two.compose": "حرر مشاركاتك عبر عمود التحرير. يمكنك من خلاله تحميل الصور وتغيير إعدادات الخصوصية وإضافة تحذيرات عن المحتوى باستخدام الرموز أدناه.",
-  "onboarding.skip": "تخطي",
   "privacy.change": "إضبط خصوصية المنشور",
   "privacy.direct.long": "أنشر إلى المستخدمين المشار إليهم فقط",
   "privacy.direct.short": "مباشر",
@@ -250,10 +292,13 @@
   "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.cancel_reblog_private": "إلغاء الترقية",
   "status.cannot_reblog": "تعذرت ترقية هذا المنشور",
   "status.delete": "إحذف",
+  "status.detailed_status": "تفاصيل المحادثة",
   "status.direct": "رسالة خاصة إلى @{name}",
   "status.embed": "إدماج",
   "status.favourite": "أضف إلى المفضلة",
@@ -267,9 +312,11 @@
   "status.open": "وسع هذه المشاركة",
   "status.pin": "تدبيس على الملف الشخصي",
   "status.pinned": "تبويق مثبَّت",
+  "status.read_more": "اقرأ المزيد",
   "status.reblog": "رَقِّي",
   "status.reblog_private": "القيام بالترقية إلى الجمهور الأصلي",
-  "status.reblogged_by": "{name} رقى",
+  "status.reblogged_by": "رقّاه {name}",
+  "status.reblogs.empty": "لم يقم أي أحد بترقية هذا التبويق بعد. عندما يقوم أحدهم بذلك سوف تظهر هنا.",
   "status.redraft": "إزالة و إعادة الصياغة",
   "status.reply": "ردّ",
   "status.replyAll": "رُد على الخيط",
@@ -281,8 +328,11 @@
   "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": "المحلي",
@@ -291,7 +341,7 @@
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} آخرون {people}} يتحدثون",
   "ui.beforeunload": "سوف تفقد مسودتك إن تركت ماستدون.",
   "upload_area.title": "إسحب ثم أفلت للرفع",
-  "upload_button.label": "إضافة وسائط",
+  "upload_button.label": "إضافة وسائط (JPEG، PNG، GIF، WebM، MP4، MOV)",
   "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
new file mode 100644
index 0000000000000000000000000000000000000000..a9407e82dd0671d4ec77073458ed04a67a0e34bb
--- /dev/null
+++ b/app/javascript/mastodon/locales/ast.json
@@ -0,0 +1,358 @@
+{
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.badges.bot": "Robó",
+  "account.block": "Bloquiar a @{name}",
+  "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",
+  "account.follow": "Follow",
+  "account.followers": "Siguidores",
+  "account.followers.empty": "Naide sigue a esti usuariu entá.",
+  "account.follows": "Sigue a",
+  "account.follows.empty": "Esti usuariu entá nun sigue a naide.",
+  "account.follows_you": "Síguete",
+  "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": "Mentar a @{name}",
+  "account.moved_to": "{name} has moved to:",
+  "account.mute": "Silenciar a @{name}",
+  "account.mute_notifications": "Mute notifications from @{name}",
+  "account.muted": "Muted",
+  "account.posts": "Toots",
+  "account.posts_with_replies": "Toots y rempuestes",
+  "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": "Desbloquiar a @{name}",
+  "account.unblock_domain": "Amosar {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": "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",
+  "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": "Usuarios bloquiaos",
+  "column.community": "Llinia temporal llocal",
+  "column.direct": "Mensaxes direutos",
+  "column.domain_blocks": "Dominios anubríos",
+  "column.favourites": "Favoritos",
+  "column.follow_requests": "Solicitúes de siguimientu",
+  "column.home": "Aniciu",
+  "column.lists": "Llistes",
+  "column.mutes": "Usuarios silenciaos",
+  "column.notifications": "Avisos",
+  "column.pins": "Toots fixaos",
+  "column.public": "Llinia temporal federada",
+  "column_back_button.label": "Atrás",
+  "column_header.hide_settings": "Hide settings",
+  "column_header.moveLeft_settings": "Mover la columna a la esquierda",
+  "column_header.moveRight_settings": "Mover la columna a la drecha",
+  "column_header.pin": "Fixar",
+  "column_header.show_settings": "Show settings",
+  "column_header.unpin": "Desfixar",
+  "column_subheading.settings": "Axustes",
+  "community.column_settings.media_only": "Media Only",
+  "compose_form.direct_message_warning": "Esti toot namái va unviase a los usuarios mentaos.",
+  "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": "¿En qué pienses?",
+  "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": "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.confirm": "Block",
+  "confirmations.block.message": "¿De xuru que quies bloquiar a {name}?",
+  "confirmations.delete.confirm": "Delete",
+  "confirmations.delete.message": "¿De xuru que quies desaniciar esti estáu?",
+  "confirmations.delete_list.confirm": "Desaniciar",
+  "confirmations.delete_list.message": "¿De xuru que quies desaniciar dafechu esta llista?",
+  "confirmations.domain_block.confirm": "Anubrir tol dominiu",
+  "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": "¿De xuru que quies silenciar a {name}?",
+  "confirmations.redraft.confirm": "Desaniciar y reeditar",
+  "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": "¿De xuru que quies dexar de siguir a {name}?",
+  "embed.instructions": "Empotra esti estáu nun sitiu web copiando'l códigu d'embaxo.",
+  "embed.preview": "Asina ye como va vese:",
+  "emoji_button.activity": "Actividaes",
+  "emoji_button.custom": "Custom",
+  "emoji_button.flags": "Banderes",
+  "emoji_button.food": "Comida y bébora",
+  "emoji_button.label": "Insert emoji",
+  "emoji_button.nature": "Natura",
+  "emoji_button.not_found": "¡Nun hai fustaxes! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Oxetos",
+  "emoji_button.people": "Xente",
+  "emoji_button.recent": "Úsase davezu",
+  "emoji_button.search": "Guetar...",
+  "emoji_button.search_results": "Search results",
+  "emoji_button.symbols": "Símbolos",
+  "emoji_button.travel": "Viaxes y llugares",
+  "empty_column.account_timeline": "No toots here!",
+  "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í.",
+  "empty_column.domain_blocks": "Entá nun hai dominios anubríos.",
+  "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": "Entá nun tienes denguna solicitú de siguimientu. Cuando recibas una, va amosase equí.",
+  "empty_column.hashtag": "There is nothing in this hashtag yet.",
+  "empty_column.home": "¡Tienes la llinia temporal balera! Visita {public} o usa la gueta pa entamar y conocer a otros usuarios.",
+  "empty_column.home.public_timeline": "la llinia temporal pública",
+  "empty_column.list": "Entá nun hai nada nesta llista. Cuando los miembros d'esta llista espublicen estaos nuevos, van apaecer equí.",
+  "empty_column.lists": "Entá nun tienes denguna llista. Cuando crees una, va amosase equí.",
+  "empty_column.mutes": "Entá nun silenciesti a dengún usuariu.",
+  "empty_column.notifications": "Entá nun tienes dengún avisu. Interactua con otros p'aniciar la conversación.",
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
+  "follow_request.authorize": "Autorizar",
+  "follow_request.reject": "Refugar",
+  "getting_started.developers": "Desendolcadores",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Documentación",
+  "getting_started.heading": "Entamu",
+  "getting_started.invite": "Convidar xente",
+  "getting_started.open_source_notice": "Mastodon ye software de códigu abiertu. Pues collaborar o informar de fallos en {github} (GitHub).",
+  "getting_started.security": "Seguranza",
+  "getting_started.terms": "Términos del serviciu",
+  "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": "Amosar toots compartíos",
+  "home.column_settings.show_replies": "Amosar rempuestes",
+  "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": "pa dir p'atrás",
+  "keyboard_shortcuts.blocked": "p'abrir la llista d'usuarios bloquiaos",
+  "keyboard_shortcuts.boost": "pa compartir un toot",
+  "keyboard_shortcuts.column": "to focus a status in one of the columns",
+  "keyboard_shortcuts.compose": "to focus the compose textarea",
+  "keyboard_shortcuts.description": "Descripción",
+  "keyboard_shortcuts.direct": "p'abrir la columna de los mensaxes direutos",
+  "keyboard_shortcuts.down": "pa baxar na llista",
+  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.favourite": "to favourite",
+  "keyboard_shortcuts.favourites": "p'abrir la llista de favoritos",
+  "keyboard_shortcuts.federated": "p'abrir la llinia temporal federada",
+  "keyboard_shortcuts.heading": "Atayos del tecláu",
+  "keyboard_shortcuts.home": "p'abrir la llinia temporal d'aniciu",
+  "keyboard_shortcuts.hotkey": "Atayu",
+  "keyboard_shortcuts.legend": "p'amosar esta lleenda",
+  "keyboard_shortcuts.local": "p'abrir la llinia temporal llocal",
+  "keyboard_shortcuts.mention": "pa mentar al autor",
+  "keyboard_shortcuts.muted": "p'abrir la llista d'usuarios silenciaos",
+  "keyboard_shortcuts.my_profile": "to open your profile",
+  "keyboard_shortcuts.notifications": "p'abrir la columna d'avisos",
+  "keyboard_shortcuts.pinned": "p'abrir la llista de toots fixaos",
+  "keyboard_shortcuts.profile": "p'abrir el perfil del autor",
+  "keyboard_shortcuts.reply": "pa responder",
+  "keyboard_shortcuts.requests": "p'abrir la llista de solicitúes de siguimientu",
+  "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.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",
+  "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.new.create": "Add list",
+  "lists.new.title_placeholder": "Títulu nuevu de la llista",
+  "lists.search": "Guetar ente la xente que sigues",
+  "lists.subheading": "Les tos llistes",
+  "loading_indicator.label": "Cargando...",
+  "media_gallery.toggle_visible": "Toggle visibility",
+  "missing_indicator.label": "Nun s'alcontró",
+  "missing_indicator.sublabel": "Esti recursu nun pudo alcontrase",
+  "mute_modal.hide_notifications": "Hide notifications from this user?",
+  "navigation_bar.apps": "Aplicaciones pa móviles",
+  "navigation_bar.blocks": "Usuarios bloquiaos",
+  "navigation_bar.community_timeline": "Llinia temporal llocal",
+  "navigation_bar.compose": "Compose new toot",
+  "navigation_bar.direct": "Mensaxes direutos",
+  "navigation_bar.discover": "Discover",
+  "navigation_bar.domain_blocks": "Dominios anubríos",
+  "navigation_bar.edit_profile": "Editar el perfil",
+  "navigation_bar.favourites": "Favoritos",
+  "navigation_bar.filters": "Pallabres silenciaes",
+  "navigation_bar.follow_requests": "Solicitúes de siguimientu",
+  "navigation_bar.info": "Tocante a esta instancia",
+  "navigation_bar.keyboard_shortcuts": "Atayos",
+  "navigation_bar.lists": "Llistes",
+  "navigation_bar.logout": "Zarrar sesión",
+  "navigation_bar.mutes": "Usuarios silenciaos",
+  "navigation_bar.personal": "Personal",
+  "navigation_bar.pins": "Toots fixaos",
+  "navigation_bar.preferences": "Preferencies",
+  "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.reblog": "{name} compartió'l to estáu",
+  "notifications.clear": "Llimpiar avisos",
+  "notifications.clear_confirmation": "¿De xuru que quies llimpiar dafechu tolos avisos?",
+  "notifications.column_settings.alert": "Avisos d'escritoriu",
+  "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.follow": "Siguidores nuevos:",
+  "notifications.column_settings.mention": "Menciones:",
+  "notifications.column_settings.push": "Push notifications",
+  "notifications.column_settings.reblog": "Toots compartíos:",
+  "notifications.column_settings.show": "Amosar en columna",
+  "notifications.column_settings.sound": "Reproducir soníu",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.group": "{count} avisos",
+  "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": "Namái siguidores",
+  "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": "Cargando…",
+  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "relative_time.days": "{number}d",
+  "relative_time.hours": "{number}h",
+  "relative_time.just_now": "agora",
+  "relative_time.minutes": "{number}m",
+  "relative_time.seconds": "{number}s",
+  "reply_indicator.cancel": "Encaboxar",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.placeholder": "Comentarios adicionales",
+  "report.submit": "Submit",
+  "report.target": "Report {target}",
+  "search.placeholder": "Search",
+  "search_popout.search_format": "Formatu de gueta avanzada",
+  "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": "etiqueta",
+  "search_popout.tips.status": "estáu",
+  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
+  "search_popout.tips.user": "usuariu",
+  "search_results.accounts": "Xente",
+  "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.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
+  "status.direct": "Unviar un mensaxe direutu a @{name}",
+  "status.embed": "Empotrar",
+  "status.favourite": "Favourite",
+  "status.filtered": "Filtered",
+  "status.load_more": "Cargar más",
+  "status.media_hidden": "Mediu anubríu",
+  "status.mention": "Mentar a @{name}",
+  "status.more": "Más",
+  "status.mute": "Silenciar a @{name}",
+  "status.mute_conversation": "Silenciar la conversación",
+  "status.open": "Espander esti estáu",
+  "status.pin": "Fixar nel perfil",
+  "status.pinned": "Toot fixáu",
+  "status.read_more": "Read more",
+  "status.reblog": "Compartir",
+  "status.reblog_private": "Compartir cola audiencia orixinal",
+  "status.reblogged_by": "{name} compartió",
+  "status.reblogs.empty": "Naide nun compartió esti toot entá. Cuando daquién lo faiga, va amosase equí.",
+  "status.redraft": "Desaniciar y reeditar",
+  "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",
+  "status.show_less_all": "Show less for all",
+  "status.show_more": "Amosar más",
+  "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
+  "status.unmute_conversation": "Unmute conversation",
+  "status.unpin": "Desfixar del perfil",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
+  "tabs_bar.federated_timeline": "Federated",
+  "tabs_bar.home": "Aniciu",
+  "tabs_bar.local_timeline": "Llocal",
+  "tabs_bar.notifications": "Avisos",
+  "tabs_bar.search": "Search",
+  "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_form.description": "Descripción pa discapacitaos visuales",
+  "upload_form.focus": "Crop",
+  "upload_form.undo": "Desaniciar",
+  "upload_progress.label": "Xubiendo...",
+  "video.close": "Zarrar el videu",
+  "video.exit_fullscreen": "Colar de la pantalla completa",
+  "video.expand": "Espander el videu",
+  "video.fullscreen": "Pantalla completa",
+  "video.hide": "Anubrir el videu",
+  "video.mute": "Silenciar el soníu",
+  "video.pause": "Posar",
+  "video.play": "Reproducir",
+  "video.unmute": "Unmute sound"
+}
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index c788b8c61738327aeff8b9990669b8ab21be5976..a812f5cb1a5b4e898ba9a2623ebfae7d77fd9d89 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Блокирай",
   "account.block_domain": "Hide everything from {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Последвай",
   "account.followers": "Последователи",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Следвам",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.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": "Споменаване",
   "account.moved_to": "{name} has moved to:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Show boosts from @{name}",
   "account.unblock": "Не блокирай",
   "account.unblock_domain": "Unhide {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Не следвай",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
@@ -86,6 +93,8 @@
   "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.",
@@ -104,41 +113,86 @@
   "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.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Първи стъпки",
   "getting_started.invite": "Invite people",
   "getting_started.open_source_notice": "Mastodon е софтуер с отворен код. Можеш да помогнеш или да докладваш за проблеми в Github: {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",
+  "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.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
@@ -159,8 +213,10 @@
   "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",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
   "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.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
   "notifications.column_settings.reblog": "Споделяния:",
   "notifications.column_settings.show": "Покажи в колона",
   "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",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
-  "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -250,10 +292,13 @@
   "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.delete": "Изтриване",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Предпочитани",
@@ -267,9 +312,11 @@
   "status.open": "Expand this status",
   "status.pin": "Pin on profile",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "Споделяне",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "{name} сподели",
+  "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": "Отговор",
   "status.replyAll": "Reply to thread",
@@ -281,8 +328,11 @@
   "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": "Начало",
   "tabs_bar.local_timeline": "Local",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 408f5ced7b618e10df017c22437405802a51f85c..07a4f01746c3b8e08325a639552d4747d6dbda0a 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Afegir o Treure de les llistes",
   "account.badges.bot": "Bot",
   "account.block": "Bloca @{name}",
   "account.block_domain": "Amaga-ho tot de {domain}",
@@ -7,11 +8,16 @@
   "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.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.mention": "Esmentar @{name}",
   "account.moved_to": "{name} s'ha mogut a:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Mostra els impulsos de @{name}",
   "account.unblock": "Desbloca @{name}",
   "account.unblock_domain": "Mostra {domain}",
+  "account.unendorse": "No es mostren al perfil",
   "account.unfollow": "Deixa de seguir",
   "account.unmute": "Treure silenci de @{name}",
   "account.unmute_notifications": "Activar notificacions de @{name}",
@@ -85,7 +92,9 @@
   "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 les respostes, impulsos i favorits.",
+  "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.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ó.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Resultats de la cerca",
   "emoji_button.symbols": "Símbols",
   "emoji_button.travel": "Viatges i Llocs",
+  "empty_column.account_timeline": "No hi ha toots aquí!",
+  "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.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.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.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",
   "follow_request.authorize": "Autoritzar",
   "follow_request.reject": "Rebutjar",
   "getting_started.developers": "Desenvolupadors",
+  "getting_started.directory": "Directori de perfils",
   "getting_started.documentation": "Documentació",
-  "getting_started.find_friends": "Troba amics de Twitter",
   "getting_started.heading": "Començant",
   "getting_started.invite": "Convida gent",
   "getting_started.open_source_notice": "Mastodon és un programari de codi obert. Pots contribuir o informar de problemes a GitHub a {github}.",
   "getting_started.security": "Seguretat",
   "getting_started.terms": "Termes del servei",
+  "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.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",
   "home.column_settings.basic": "Bàsic",
   "home.column_settings.show_reblogs": "Mostrar impulsos",
   "home.column_settings.show_replies": "Mostrar respostes",
+  "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.",
+  "introduction.federation.home.headline": "Inici",
+  "introduction.federation.home.text": "Les publicacions de les persones que segueixes apareixeran a la línia de temps Inici. Pots seguir qualsevol persona de qualsevol servidor!",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Les publicacions públiques de les persones del teu mateix servidor apareixeran a la línia de temps local.",
+  "introduction.interactions.action": "Finalitza el tutorial!",
+  "introduction.interactions.favourite.headline": "Favorit",
+  "introduction.interactions.favourite.text": "Pots desar un toot per a més tard i deixar que l'autor sàpiga que t'ha agradat, marcant-lo com a favorit.",
+  "introduction.interactions.reblog.headline": "Impuls",
+  "introduction.interactions.reblog.text": "Pots compartir amb els teus seguidors els toots d'altres usuaris, impulsant-los.",
+  "introduction.interactions.reply.headline": "Respondre",
+  "introduction.interactions.reply.text": "Pots respondre als toots d'altres persones i als teus propis, que els unirà en una conversa.",
+  "introduction.welcome.action": "Som-hi!",
+  "introduction.welcome.headline": "Primers passos",
+  "introduction.welcome.text": "Benvingut al fedivers! En uns moments podràs emetre missatges i conversar amb els teus amics en una gran varietat de servidors. Però aquest servidor, {domain}, és especial: allotja el teu perfil així que recorda el seu nom.",
   "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.compose": "per centrar l'area de composició de text",
   "keyboard_shortcuts.description": "Description",
+  "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.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.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.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.toggle_hidden": "per a mostrar/amagar text sota CW",
   "keyboard_shortcuts.toot": "per a començar un toot nou de trinca",
   "keyboard_shortcuts.unfocus": "descentrar l'area de composició de text/cerca",
@@ -159,14 +213,16 @@
   "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.blocks": "Usuaris bloquejats",
   "navigation_bar.community_timeline": "Línia de temps Local",
+  "navigation_bar.compose": "Redacta nou toot",
   "navigation_bar.direct": "Missatges directes",
   "navigation_bar.discover": "Descobreix",
   "navigation_bar.domain_blocks": "Dominis ocults",
   "navigation_bar.edit_profile": "Editar perfil",
   "navigation_bar.favourites": "Favorits",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Paraules silenciades",
   "navigation_bar.follow_requests": "Sol·licituds de seguiment",
   "navigation_bar.info": "Informació addicional",
   "navigation_bar.keyboard_shortcuts": "Dreceres de teclat",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Estàs segur que vols esborrar permanenment totes les teves notificacions?",
   "notifications.column_settings.alert": "Notificacions d'escriptori",
   "notifications.column_settings.favourite": "Favorits:",
+  "notifications.column_settings.filter_bar.advanced": "Mostra totes les categories",
+  "notifications.column_settings.filter_bar.category": "Barra ràpida de filtres",
+  "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.push_meta": "Aquest dispositiu",
   "notifications.column_settings.reblog": "Impulsos:",
   "notifications.column_settings.show": "Mostrar en la columna",
   "notifications.column_settings.sound": "Reproduïr so",
+  "notifications.filter.all": "Tots",
+  "notifications.filter.boosts": "Impulsos",
+  "notifications.filter.favourites": "Favorits",
+  "notifications.filter.follows": "Seguiments",
+  "notifications.filter.mentions": "Mencions",
   "notifications.group": "{count} notificacions",
-  "onboarding.done": "Fet",
-  "onboarding.next": "Següent",
-  "onboarding.page_five.public_timelines": "La línia de temps local mostra missatges públics de tothom de {domain}. La línia de temps federada mostra els missatges públics de tothom que la gent de {domain} segueix. Aquests són les línies de temps Públiques, una bona manera de descobrir noves persones.",
-  "onboarding.page_four.home": "La línia de temps d'Inici mostra missatges de les persones que segueixes.",
-  "onboarding.page_four.notifications": "La columna Notificacions mostra quan algú interactua amb tu.",
-  "onboarding.page_one.federation": "Mastodon és una xarxa de servidors independents que s'uneixen per fer una xarxa social encara més gran. A aquests servidors els hi diem instàncies.",
-  "onboarding.page_one.full_handle": "El teu usuari complet",
-  "onboarding.page_one.handle_hint": "Això és el que els hi diries als teus amics que cerquin.",
-  "onboarding.page_one.welcome": "Benvingut a Mastodon!",
-  "onboarding.page_six.admin": "L'administrador de la teva instància és {admin}.",
-  "onboarding.page_six.almost_done": "Quasi fet...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Hi ha {apps} disponibles per iOS, Android i altres plataformes.",
-  "onboarding.page_six.github": "Mastodon és un programari de codi obert. Pots informar d'errors, sol·licitar característiques o contribuir en el codi a {github}.",
-  "onboarding.page_six.guidelines": "Normes de la comunitat",
-  "onboarding.page_six.read_guidelines": "Si us plau llegeix les {guidelines} de {domain}!",
-  "onboarding.page_six.various_app": "aplicacions per mòbils",
-  "onboarding.page_three.profile": "Edita el teu perfil per canviar el teu avatar, bio o el nom de visualització. També hi trobaràs altres preferències.",
-  "onboarding.page_three.search": "Utilitza la barra de cerca per trobar gent i mirar etiquetes, com a {illustration} i {introductions}. Per buscar una persona que no està en aquesta instància, utilitza tot el seu nom d'usuari complert.",
-  "onboarding.page_two.compose": "Escriu missatges en la columna de redacció. Pots pujar imatges, canviar la configuració de privacitat i afegir les advertències de contingut amb les icones de sota.",
-  "onboarding.skip": "Omet",
   "privacy.change": "Ajusta l'estat de privacitat",
   "privacy.direct.long": "Publicar només per als usuaris esmentats",
   "privacy.direct.short": "Directe",
@@ -250,14 +292,17 @@
   "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, un {result} altres {results}}",
   "standalone.public_title": "Una mirada a l'interior ...",
+  "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.cancel_reblog_private": "Desfer l'impuls",
   "status.cannot_reblog": "Aquesta publicació no pot ser retootejada",
   "status.delete": "Esborrar",
+  "status.detailed_status": "Visualització detallada de la conversa",
   "status.direct": "Missatge directe @{name}",
   "status.embed": "Incrustar",
   "status.favourite": "Favorit",
-  "status.filtered": "Filtered",
+  "status.filtered": "Filtrat",
   "status.load_more": "Carrega més",
   "status.media_hidden": "Multimèdia amagat",
   "status.mention": "Esmentar @{name}",
@@ -267,9 +312,11 @@
   "status.open": "Ampliar aquest estat",
   "status.pin": "Fixat en el perfil",
   "status.pinned": "Toot fixat",
+  "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.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",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Mostra menys per a tot",
   "status.show_more": "Mostra més",
   "status.show_more_all": "Mostra més per a tot",
+  "status.show_thread": "Mostra el fil",
   "status.unmute_conversation": "Activar conversació",
   "status.unpin": "Deslliga del perfil",
+  "suggestions.dismiss": "Descartar suggeriment",
+  "suggestions.header": "És possible que estiguis interessat en…",
   "tabs_bar.federated_timeline": "Federada",
   "tabs_bar.home": "Inici",
   "tabs_bar.local_timeline": "Local",
@@ -291,9 +341,9 @@
   "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",
-  "upload_button.label": "Afegir multimèdia",
+  "upload_button.label": "Afegir multimèdia (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Descriure els problemes visuals",
-  "upload_form.focus": "Retallar",
+  "upload_form.focus": "Modificar la previsualització",
   "upload_form.undo": "Esborra",
   "upload_progress.label": "Pujant...",
   "video.close": "Tancar el vídeo",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index 1e7090a199a51b47ad08db01931371219e21cb07..496f13e7d58f698b374572d2477f7b9ffbf5ba90 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Aghjustà o toglie da e liste",
   "account.badges.bot": "Bot",
   "account.block": "Bluccà @{name}",
   "account.block_domain": "Piattà tuttu da {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Siguità",
   "account.followers": "Abbunati",
+  "account.followers.empty": "Nisunu hè abbunatu à st'utilizatore.",
   "account.follows": "Abbunamenti",
+  "account.follows.empty": "St'utilizatore ùn seguita nisunu.",
   "account.follows_you": "Vi seguita",
   "account.hide_reblogs": "Piattà spartere da @{name}",
+  "account.link_verified_on": "A prupietà di stu ligame hè stata verificata u {date}",
+  "account.locked_info": "U statutu di vita privata di u contu hè chjosu. U pruprietariu esamina manualmente e dumande d'abbunamentu.",
   "account.media": "Media",
   "account.mention": "Mintuvà @{name}",
   "account.moved_to": "{name} hè partutu nant'à:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Vede spartere da @{name}",
   "account.unblock": "Sbluccà @{name}",
   "account.unblock_domain": "Ùn piattà più {domain}",
+  "account.unendorse": "Ùn fà figurà nant'à u prufilu",
   "account.unfollow": "Ùn siguità più",
   "account.unmute": "Ùn piattà più @{name}",
   "account.unmute_notifications": "Ùn piattà più nutificazione da @{name}",
@@ -59,9 +66,9 @@
   "column_header.show_settings": "Mustrà i parametri",
   "column_header.unpin": "Spuntarulà",
   "column_subheading.settings": "Parametri",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Solu media",
   "compose_form.direct_message_warning": "Solu l'utilizatori mintuvati puderenu vede stu statutu.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "compose_form.direct_message_warning_learn_more": "Amparà di più",
   "compose_form.hashtag_warning": "Stu statutu ùn hè \"Micca listatu\" è ùn sarà micca listatu indè e circate da hashtag. Per esse vistu in quesse, u statutu deve esse \"Pubblicu\".",
   "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",
@@ -81,11 +88,13 @@
   "confirmations.delete_list.confirm": "Toglie",
   "confirmations.delete_list.message": "Site sicuru·a che vulete supprime sta lista?",
   "confirmations.domain_block.confirm": "Piattà tuttu u duminiu",
-  "confirmations.domain_block.message": "Site sicuru·a che vulete piattà tuttu à {domain}? Saria forse abbastanza di bluccà ò piattà alcuni conti da quallà.",
+  "confirmations.domain_block.message": "Site sicuru·a che vulete piattà tuttu à {domain}? Saria forse abbastanza di bluccà ò piattà alcuni conti da quallà. Ùn viderete più nunda da quallà indè e linee pubbliche o e nutificazione. I vostri abbunati da stu duminiu saranu tolti.",
   "confirmations.mute.confirm": "Piattà",
   "confirmations.mute.message": "Site sicuru·a che vulete piattà @{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.redraft.confirm": "Sguassà è riscrive",
+  "confirmations.redraft.message": "Site sicuru·a chè vulete sguassà stu statutu è riscrivelu? I favuriti è spartere saranu persi, è e risposte diventeranu orfane.",
+  "confirmations.reply.confirm": "Risponde",
+  "confirmations.reply.message": "Risponde avà sguasserà u missaghju chì scrivite. Site sicuru·a chì vulete cuntinuà?",
   "confirmations.unfollow.confirm": "Disabbunassi",
   "confirmations.unfollow.message": "Site sicuru·a ch'ùn vulete più siguità @{name}?",
   "embed.instructions": "Integrà stu statutu à u vostru situ cù u codice quì sottu.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Risultati di a cerca",
   "emoji_button.symbols": "Simbuli",
   "emoji_button.travel": "Lochi è Viaghju",
+  "empty_column.account_timeline": "Nisun statutu quì!",
+  "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ì.",
+  "empty_column.domain_blocks": "Ùn c'hè manc'un duminiu bluccatu avà.",
+  "empty_column.favourited_statuses": "Ùn avete manc'unu statutu favuritu. Quandu aghjusterate unu à i vostri favuriti, sarà mustratu quì.",
+  "empty_column.favourites": "Nisunu hà aghjustatu stu statutu à i so favuriti. Quandu qualch'unu farà quessa, u so contu sarà mustratu quì.",
+  "empty_column.follow_requests": "Ùn avete manc'una dumanda d'abbunamentu. Quandu averete una, sarà mustrata quì.",
   "empty_column.hashtag": "Ùn c'hè ancu nunda quì.",
   "empty_column.home": "A vostr'accolta hè viota! Pudete andà nant'à {public} o pruvà a ricerca per truvà parsone da siguità.",
   "empty_column.home.public_timeline": "a linea pubblica",
   "empty_column.list": "Ùn c'hè ancu nunda quì. Quandu membri di sta lista manderanu novi statuti, i vidarete quì.",
+  "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",
   "follow_request.authorize": "Auturizà",
   "follow_request.reject": "Righjittà",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Sviluppatori",
+  "getting_started.directory": "Annuariu di i prufili",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Per principià",
-  "getting_started.invite": "Invite people",
+  "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}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
+  "getting_started.security": "Sicurità",
+  "getting_started.terms": "Cundizione di u serviziu",
+  "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.tag_mode.all": "Tutti quessi",
+  "hashtag.column_settings.tag_mode.any": "Unu di quessi",
+  "hashtag.column_settings.tag_mode.none": "Nisunu di quessi",
+  "hashtag.column_settings.tag_toggle": "Inchjude tag addiziunali per sta colonna",
   "home.column_settings.basic": "Bàsichi",
   "home.column_settings.show_reblogs": "Vede e spartere",
   "home.column_settings.show_replies": "Vede e risposte",
+  "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.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",
+  "introduction.federation.local.text": "I statuti pubblichi da quelli chì sò nant'a listessu servore chì voi ponu esse visti indè a linea pubblica lucale.",
+  "introduction.interactions.action": "Finisce u tutoriale!",
+  "introduction.interactions.favourite.headline": "Favuritu",
+  "introduction.interactions.favourite.text": "Pudete salvà un statutu per ritruvallu più tardi, è fà sapè à l'autore chì v'hè piaciutu, l'aghustendu à i vostri favuriti.",
+  "introduction.interactions.reblog.headline": "Sparte",
+  "introduction.interactions.reblog.text": "Pudete sparte i statuti d'altre persone à i vostri abbunati cù u buttone di spartera.",
+  "introduction.interactions.reply.headline": "Risponde",
+  "introduction.interactions.reply.text": "Pudete risponde à d'altre persone o a i vostri propii statuti, cio chì i ligarà indè una cunversazione.",
+  "introduction.welcome.action": "Andemu!",
+  "introduction.welcome.headline": "Primi passi",
+  "introduction.welcome.text": "Benvenutu·a indè u fediverse! In qualchi minuta, puderete diffonde missaghji è parlà à i vostri amichi nant'à una varietà maiò di servori. Mà quess'istanza, {domain}, hè speciale—ghjè induve hè uspitatu u vostru prufile, allora ricurdatevi di u so nome.",
   "keyboard_shortcuts.back": "rivultà",
+  "keyboard_shortcuts.blocked": "per apre una lista d'utilizatori bluccati",
   "keyboard_shortcuts.boost": "sparte",
   "keyboard_shortcuts.column": "fucalizà un statutu indè una colonna",
   "keyboard_shortcuts.compose": "fucalizà nant'à l'area di ridazzione",
   "keyboard_shortcuts.description": "Descrizzione",
+  "keyboard_shortcuts.direct": "per apre una culonna di missaghji diretti",
   "keyboard_shortcuts.down": "falà indè a lista",
   "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.heading": "Accorte cù a tastera",
+  "keyboard_shortcuts.home": "per apre a linea d'accolta",
   "keyboard_shortcuts.hotkey": "Accorta",
   "keyboard_shortcuts.legend": "vede a legenda",
+  "keyboard_shortcuts.local": "per apre a linea pubblica lucale",
   "keyboard_shortcuts.mention": "mintuvà l'autore",
+  "keyboard_shortcuts.muted": "per apre a lista di l'utilizatori piattati",
+  "keyboard_shortcuts.my_profile": "per apre u vostru prufile",
+  "keyboard_shortcuts.notifications": "per apre a culonna di nutificazione",
+  "keyboard_shortcuts.pinned": "per apre a lista di statuti puntarulati",
+  "keyboard_shortcuts.profile": "per apre u prufile di l'autore",
   "keyboard_shortcuts.reply": "risponde",
+  "keyboard_shortcuts.requests": "per apre a lista di dumande d'abbunamentu",
   "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.toot": "scrive un novu statutu",
   "keyboard_shortcuts.unfocus": "ùn fucalizà più l'area di testu",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Micca trovu",
   "missing_indicator.sublabel": "Ùn era micca pussivule di truvà sta risorsa",
   "mute_modal.hide_notifications": "Piattà nutificazione da st'utilizatore?",
+  "navigation_bar.apps": "Applicazione per u telefuninu",
   "navigation_bar.blocks": "Utilizatori bluccati",
   "navigation_bar.community_timeline": "Linea pubblica lucale",
+  "navigation_bar.compose": "Scrive un novu statutu",
   "navigation_bar.direct": "Missaghji diretti",
-  "navigation_bar.discover": "Discover",
+  "navigation_bar.discover": "Scopre",
   "navigation_bar.domain_blocks": "Duminii piattati",
   "navigation_bar.edit_profile": "Mudificà u prufile",
   "navigation_bar.favourites": "Favuriti",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Parolle silenzate",
   "navigation_bar.follow_requests": "Dumande d'abbunamentu",
   "navigation_bar.info": "À prupositu di l'istanza",
   "navigation_bar.keyboard_shortcuts": "Accorte cù a tastera",
@@ -177,7 +233,7 @@
   "navigation_bar.pins": "Statuti puntarulati",
   "navigation_bar.preferences": "Preferenze",
   "navigation_bar.public_timeline": "Linea pubblica glubale",
-  "navigation_bar.security": "Security",
+  "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",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Site sicuru·a che vulete toglie tutte ste nutificazione?",
   "notifications.column_settings.alert": "Nutificazione nant'à l'urdinatore",
   "notifications.column_settings.favourite": "Favuriti:",
+  "notifications.column_settings.filter_bar.advanced": "Affissà tutte e categurie",
+  "notifications.column_settings.filter_bar.category": "Barra di ricerca pronta",
+  "notifications.column_settings.filter_bar.show": "Mustrà",
   "notifications.column_settings.follow": "Abbunati novi:",
   "notifications.column_settings.mention": "Minzione:",
   "notifications.column_settings.push": "Nutificazione Push",
-  "notifications.column_settings.push_meta": "Quess'apparechju",
   "notifications.column_settings.reblog": "Spartere:",
   "notifications.column_settings.show": "Mustrà indè a colonna",
   "notifications.column_settings.sound": "Sunà",
-  "notifications.group": "{count} notifications",
-  "onboarding.done": "Fatta",
-  "onboarding.next": "Siguente",
-  "onboarding.page_five.public_timelines": "A linea pubblica lucale mostra statuti pubblichi da tuttu u mondu nant'à {domain}. A linea pubblica glubale mostra ancu quelli di a ghjente seguitata da l'utilizatori di {domain}. Quesse sò una bona manera d'incuntrà nove parsone.",
-  "onboarding.page_four.home": "A linea d'accolta mostra i statuti di i vostr'abbunamenti.",
-  "onboarding.page_four.notifications": "A colonna di nutificazione mostra l'interazzione ch'altre parsone anu cù u vostru contu.",
-  "onboarding.page_one.federation": "Mastodon ghjè una rete di servori independenti, chjamati istanze, uniti indè una sola rete suciale.",
-  "onboarding.page_one.full_handle": "U vostru identificatore cumplettu",
-  "onboarding.page_one.handle_hint": "Quessu ghjè cio chì direte à i vostri amichi per circavi.",
-  "onboarding.page_one.welcome": "Benvenuti/a nant'à Mastodon!",
-  "onboarding.page_six.admin": "L'amministratore di a vostr'istanza hè {admin}.",
-  "onboarding.page_six.almost_done": "Quasgi finitu...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Ci sò {apps} dispunibule per iOS, Android è altre piattaforme.",
-  "onboarding.page_six.github": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un prublemu, nant'à {github}.",
-  "onboarding.page_six.guidelines": "regule di a cumunità",
-  "onboarding.page_six.read_guidelines": "Ùn vi scurdate di leghje e {guidelines} di {domain}!",
-  "onboarding.page_six.various_app": "applicazione pè u telefuninu",
-  "onboarding.page_three.profile": "Pudete mudificà u prufile per cambia u ritrattu, a descrizzione è u nome affissatu. Ci sò ancu alcun'altre preferenze.",
-  "onboarding.page_three.search": "Fate usu di l'area di ricerca per truvà altre persone è vede hashtag cum'è {illustration} o {introductions}. Per vede qualcunu ch'ùn hè micca nant'à st'istanza, cercate u so identificatore complettu (pare un'email).",
-  "onboarding.page_two.compose": "I statuti è missaghji si scrivenu indè l'area di ridazzione. Pudete caricà imagine, cambià i parametri di pubblicazione, è mette avertimenti di cuntenuti cù i buttoni quì sottu.",
-  "onboarding.skip": "Passà",
+  "notifications.filter.all": "Tuttu",
+  "notifications.filter.boosts": "Spartere",
+  "notifications.filter.favourites": "Favuriti",
+  "notifications.filter.follows": "Abbunamenti",
+  "notifications.filter.mentions": "Minzione",
+  "notifications.group": "{count} nutificazione",
   "privacy.change": "Mudificà a cunfidenzialità di u statutu",
   "privacy.direct.long": "Mandà solu à quelli chì so mintuvati",
   "privacy.direct.short": "Direttu",
@@ -249,15 +291,18 @@
   "search_results.hashtags": "Hashtag",
   "search_results.statuses": "Statuti",
   "search_results.total": "{count, number} {count, plural, one {risultatu} other {risultati}}",
-  "standalone.public_title": "Una vista di...",
+  "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.delete": "Toglie",
+  "status.detailed_status": "Vista in ditagliu di a cunversazione",
   "status.direct": "Mandà un missaghju @{name}",
   "status.embed": "Integrà",
   "status.favourite": "Aghjunghje à i favuriti",
-  "status.filtered": "Filtered",
+  "status.filtered": "Filtratu",
   "status.load_more": "Vede di più",
   "status.media_hidden": "Media piattata",
   "status.mention": "Mintuvà @{name}",
@@ -267,10 +312,12 @@
   "status.open": "Apre stu statutu",
   "status.pin": "Puntarulà à u prufile",
   "status.pinned": "Statutu puntarulatu",
+  "status.read_more": "Leghje di più",
   "status.reblog": "Sparte",
   "status.reblog_private": "Sparte à l'audienza uriginale",
   "status.reblogged_by": "{name} hà spartutu",
-  "status.redraft": "Delete & re-draft",
+  "status.reblogs.empty": "Per avà nisunu hà spartutu u statutu. Quandu qualch'unu u sparterà, u so contu sarà mustratu quì.",
+  "status.redraft": "Sguassà è riscrive",
   "status.reply": "Risponde",
   "status.replyAll": "Risponde à tutti",
   "status.report": "Palisà @{name}",
@@ -281,19 +328,22 @@
   "status.show_less_all": "Ripiegà tuttu",
   "status.show_more": "Slibrà",
   "status.show_more_all": "Slibrà tuttu",
+  "status.show_thread": "Vede u filu",
   "status.unmute_conversation": "Ùn piattà più a cunversazione",
   "status.unpin": "Spuntarulà da u prufile",
+  "suggestions.dismiss": "Righjittà a pruposta",
+  "suggestions.header": "Site forse interessatu·a da…",
   "tabs_bar.federated_timeline": "Glubale",
   "tabs_bar.home": "Accolta",
   "tabs_bar.local_timeline": "Lucale",
   "tabs_bar.notifications": "Nutificazione",
   "tabs_bar.search": "Cercà",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "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",
+  "upload_button.label": "Aghjunghje un media (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Discrive per i malvistosi",
-  "upload_form.focus": "Riquatrà",
+  "upload_form.focus": "Cambià a vista",
   "upload_form.undo": "Sguassà",
   "upload_progress.label": "Caricamentu...",
   "video.close": "Chjudà a video",
diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json
index 59d7c403b8c9bf0fae30d872109bcd468ef252dc..e11e0be93e73d5f4585f50e678884b9469aa5693 100644
--- a/app/javascript/mastodon/locales/cs.json
+++ b/app/javascript/mastodon/locales/cs.json
@@ -1,308 +1,358 @@
 {
+  "account.add_or_remove_from_list": "Přidat nebo odstranit ze seznamů",
   "account.badges.bot": "Robot",
-  "account.block": "Blokovat @{name}",
+  "account.block": "Zablokovat uživatele @{name}",
   "account.block_domain": "Skrýt vše z {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.follow": "Follow",
-  "account.followers": "Followers",
-  "account.follows": "Follows",
-  "account.follows_you": "Follows you",
-  "account.hide_reblogs": "Hide boosts from @{name}",
-  "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.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.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.domain_blocked": "Doména skryta",
+  "account.edit_profile": "Upravit profil",
+  "account.endorse": "Představit na profilu",
+  "account.follow": "Sledovat",
+  "account.followers": "Sledovatelé",
+  "account.followers.empty": "Tohoto uživatele ještě nikdo nesleduje.",
+  "account.follows": "Sledovaní",
+  "account.follows.empty": "Tento uživatel ještě nikoho nesleduje.",
+  "account.follows_you": "Sleduje vás",
+  "account.hide_reblogs": "Skrýt boosty od uživatele @{name}",
+  "account.link_verified_on": "Vlastnictví tohoto odkazu bylo zkontrolováno {date}",
+  "account.locked_info": "Stav soukromí tohoto účtu je nastaven na zamčeno. Jeho vlastník ručně posuzuje, kdo ho může sledovat.",
+  "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_notifications": "Skrýt oznámení od uživatele @{name}",
+  "account.muted": "Ztišen/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.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",
+  "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}",
+  "bundle_column_error.body": "Při načítání tohoto komponentu se něco pokazilo.",
+  "bundle_column_error.retry": "Zkuste to znovu",
+  "bundle_column_error.title": "Chyba sítě",
+  "bundle_modal_error.close": "Zavřít",
+  "bundle_modal_error.message": "Při načítání tohoto komponentu se něco pokazilo.",
+  "bundle_modal_error.retry": "Zkusit znovu",
+  "column.blocks": "Blokovaní uživatelé",
+  "column.community": "Místní časová osa",
+  "column.direct": "Přímé zprávy",
+  "column.domain_blocks": "Skryté domény",
+  "column.favourites": "Oblíbené",
+  "column.follow_requests": "Požadavky o sledování",
+  "column.home": "Domů",
+  "column.lists": "Seznamy",
+  "column.mutes": "Ignorovaní 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.pin": "Připnout",
+  "column_header.show_settings": "Zobrazit nastavení",
+  "column_header.unpin": "Odepnout",
+  "column_subheading.settings": "Nastavení",
+  "community.column_settings.media_only": "Pouze média",
+  "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.publish": "Tootnout",
   "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? You will lose all replies, boosts and favourites to it.",
-  "confirmations.unfollow.confirm": "Unfollow",
-  "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
-  "embed.instructions": "Embed this status on your website by copying the code below.",
-  "embed.preview": "Here is what it will look like:",
-  "emoji_button.activity": "Activity",
-  "emoji_button.custom": "Custom",
-  "emoji_button.flags": "Flags",
-  "emoji_button.food": "Food & Drink",
-  "emoji_button.label": "Insert emoji",
-  "emoji_button.nature": "Nature",
-  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
-  "emoji_button.objects": "Objects",
-  "emoji_button.people": "People",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Search...",
-  "emoji_button.search_results": "Search results",
-  "emoji_button.symbols": "Symbols",
-  "emoji_button.travel": "Travel & Places",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or 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.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.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
-  "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",
-  "home.column_settings.basic": "Basic",
-  "home.column_settings.show_reblogs": "Show boosts",
-  "home.column_settings.show_replies": "Show replies",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.boost": "to boost",
-  "keyboard_shortcuts.column": "to focus a status in one of the columns",
-  "keyboard_shortcuts.compose": "to focus the compose textarea",
-  "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.down": "to move down in the list",
-  "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.hotkey": "Hotkey",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.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.blocks": "Blocked users",
-  "navigation_bar.community_timeline": "Local timeline",
-  "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",
-  "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.follow": "New followers:",
-  "notifications.column_settings.mention": "Mentions:",
-  "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
-  "notifications.column_settings.reblog": "Boosts:",
-  "notifications.column_settings.show": "Show in column",
-  "notifications.column_settings.sound": "Play sound",
-  "notifications.group": "{count} notifications",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
-  "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
-  "privacy.change": "Adjust status privacy",
-  "privacy.direct.long": "Post to mentioned users only",
-  "privacy.direct.short": "Direct",
-  "privacy.private.long": "Post to followers only",
-  "privacy.private.short": "Followers-only",
-  "privacy.public.long": "Post to public timelines",
-  "privacy.public.short": "Public",
-  "privacy.unlisted.long": "Do not show in public timelines",
-  "privacy.unlisted.short": "Unlisted",
-  "regeneration_indicator.label": "Loading…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
-  "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": "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.",
+  "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.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.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_list.confirm": "Smazat",
+  "confirmations.delete_list.message": "Jste si jistý/á, že chcete tento seznam navždy vymazat?",
+  "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.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.preview": "Takhle to bude vypadat:",
+  "emoji_button.activity": "Aktivita",
+  "emoji_button.custom": "Vlastní",
+  "emoji_button.flags": "Vlajky",
+  "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.objects": "Předměty",
+  "emoji_button.people": "Lidé",
+  "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.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.",
+  "empty_column.domain_blocks": "Ještě nejsou žádné skryté domény.",
+  "empty_column.favourited_statuses": "Ještě nemáte žádné oblíbené tooty. Pokud si nějaký oblíbíte, zobrazí se zde.",
+  "empty_column.favourites": "Tento toot si ještě nikdo neoblíbil. Pokud to někdo udělá, zobrazí se zde.",
+  "empty_column.follow_requests": "Ještě nemáte žádné požadavky o sledování. Pokud nějaký obdržíte, zobrazí se zde.",
+  "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.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.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",
+  "follow_request.authorize": "Autorizovat",
+  "follow_request.reject": "Odmítnout",
+  "getting_started.developers": "Vývojáři",
+  "getting_started.directory": "Adresář profilů",
+  "getting_started.documentation": "Dokumentace",
+  "getting_started.heading": "Začínáme",
+  "getting_started.invite": "Pozvat lidi",
+  "getting_started.open_source_notice": "Mastodon je otevřený software. Na GitHubu k němu můžete přispět nebo nahlásit chyby: {github}.",
+  "getting_started.security": "Zabezpečení",
+  "getting_started.terms": "Podmínky používání",
+  "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.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",
+  "hashtag.column_settings.tag_toggle": "Zahrnout v tomto sloupci dodatečné tagy",
+  "home.column_settings.basic": "Základní",
+  "home.column_settings.show_reblogs": "Zobrazit boosty",
+  "home.column_settings.show_replies": "Zobrazit odpovědi",
+  "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.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.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.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.",
+  "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.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.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.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.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ů",
+  "keyboard_shortcuts.profile": "k otevření autorova profilu",
+  "keyboard_shortcuts.reply": "k odpovězení",
+  "keyboard_shortcuts.requests": "k otevření seznamu požadavků o sledování",
+  "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.toot": "k napsání úplně nového tootu",
+  "keyboard_shortcuts.unfocus": "ke zrušení soustředění na psací prostor/hledání",
+  "keyboard_shortcuts.up": "k posunutí nahoru v seznamu",
+  "lightbox.close": "Zavřít",
+  "lightbox.next": "Další",
+  "lightbox.previous": "Předchozí",
+  "lists.account.add": "Přidat do seznamu",
+  "lists.account.remove": "Odebrat ze seznamu",
+  "lists.delete": "Smazat seznam",
+  "lists.edit": "Upravit seznam",
+  "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...",
+  "media_gallery.toggle_visible": "Přepínat viditelnost",
+  "missing_indicator.label": "Nenalezeno",
+  "missing_indicator.sublabel": "Tento zdroj se nepodařilo najít",
+  "mute_modal.hide_notifications": "Skrýt oznámení od tohoto uživatele?",
+  "navigation_bar.apps": "Mobilní aplikace",
+  "navigation_bar.blocks": "Blokovaní uživatelé",
+  "navigation_bar.community_timeline": "Místní časová osa",
+  "navigation_bar.compose": "Vytvořit nový toot",
+  "navigation_bar.direct": "Přímé zprávy",
+  "navigation_bar.discover": "Objevujte",
+  "navigation_bar.domain_blocks": "Skryté domény",
+  "navigation_bar.edit_profile": "Upravit profil",
+  "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.keyboard_shortcuts": "Klávesové zkratky",
+  "navigation_bar.lists": "Seznamy",
+  "navigation_bar.logout": "Odhlásit se",
+  "navigation_bar.mutes": "Ignorovaní uživatelé",
+  "navigation_bar.personal": "Osobní",
+  "navigation_bar.pins": "Připnuté tooty",
+  "navigation_bar.preferences": "Předvolby",
+  "navigation_bar.public_timeline": "Federovaná časová osa",
+  "navigation_bar.security": "Zabezpečení",
+  "notification.favourite": "{name} si oblíbil/a váš příspěvek",
+  "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",
+  "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.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.mention": "Zmínky:",
+  "notifications.column_settings.push": "Push oznámení",
+  "notifications.column_settings.reblog": "Boosty:",
+  "notifications.column_settings.show": "Zobrazit ve sloupci",
+  "notifications.column_settings.sound": "Přehrát zvuk",
+  "notifications.filter.all": "Vše",
+  "notifications.filter.boosts": "Boosty",
+  "notifications.filter.favourites": "Oblíbení",
+  "notifications.filter.follows": "Sledování",
+  "notifications.filter.mentions": "Zmínky",
+  "notifications.group": "{count} oznámení",
+  "privacy.change": "Změnit soukromí příspěvku",
+  "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.public.long": "Odeslat na veřejné časové osy",
+  "privacy.public.short": "Veřejný",
+  "privacy.unlisted.long": "Neodeslat na veřejné časové osy",
+  "privacy.unlisted.short": "Neuvedený",
+  "regeneration_indicator.label": "Načítám…",
+  "regeneration_indicator.sublabel": "Váš domovský proud se připravuje!",
+  "relative_time.days": "{number} d",
+  "relative_time.hours": "{number} h",
+  "relative_time.just_now": "teď",
+  "relative_time.minutes": "{number} m",
+  "relative_time.seconds": "{number} s",
+  "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.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.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}}",
-  "standalone.public_title": "A look inside...",
-  "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
-  "status.cannot_reblog": "This post cannot be boosted",
-  "status.delete": "Delete",
-  "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.reblog": "Boost",
-  "status.reblog_private": "Boost to original audience",
-  "status.reblogged_by": "{name} boosted",
-  "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.unmute_conversation": "Unmute conversation",
-  "status.unpin": "Unpin from profile",
-  "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",
-  "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"
+  "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.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.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.delete": "Smazat",
+  "status.detailed_status": "Detailní zobrazení konverzace",
+  "status.direct": "Poslat přímou zprávu uživateli @{name}",
+  "status.embed": "Vložit",
+  "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.pin": "Připnout na profil",
+  "status.pinned": "Připnutý toot",
+  "status.read_more": "Číst více",
+  "status.reblog": "Boostnout",
+  "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.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ě",
+  "status.show_less_all": "Zobrazit méně pro všechny",
+  "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.unpin": "Odepnout z profilu",
+  "suggestions.dismiss": "Odmítnout návrh",
+  "suggestions.header": "Mohlo 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",
+  "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_form.description": "Popis pro zrakově postižené",
+  "upload_form.focus": "Změnit náhled",
+  "upload_form.undo": "Smazat",
+  "upload_progress.label": "Nahrávám...",
+  "video.close": "Zavřít video",
+  "video.exit_fullscreen": "Ukončit celou obrazovku",
+  "video.expand": "Otevřít video",
+  "video.fullscreen": "Celá obrazovka",
+  "video.hide": "Skrýt video",
+  "video.mute": "Vypnout zvuk",
+  "video.pause": "Pauza",
+  "video.play": "Přehrát",
+  "video.unmute": "Zapnout zvuk"
 }
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
new file mode 100644
index 0000000000000000000000000000000000000000..f35b96244ebbcd05f69573b933ffa2f9fa167839
--- /dev/null
+++ b/app/javascript/mastodon/locales/cy.json
@@ -0,0 +1,358 @@
+{
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "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",
+  "account.follow": "Dilyn",
+  "account.followers": "Dilynwyr",
+  "account.followers.empty": "Nid oes neb yn dilyn y defnyddiwr hwn eto.",
+  "account.follows": "Yn dilyn",
+  "account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.",
+  "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.media": "Cyfryngau",
+  "account.mention": "Crybwyll @{name}",
+  "account.moved_to": "Mae @{name} wedi symud i:",
+  "account.mute": "Tawelu @{name}",
+  "account.mute_notifications": "Cuddio hysbysiadau o @{name}",
+  "account.muted": "Distewyd",
+  "account.posts": "Tŵtiau",
+  "account.posts_with_replies": "Tŵtiau ac atebion",
+  "account.report": "Adrodd @{name}",
+  "account.requested": "Aros am gymeradwyaeth. Cliciwch er mwyn canslo cais dilyn",
+  "account.share": "Rhannwch broffil @{name}",
+  "account.show_reblogs": "Dangos bwstiau o @{name}",
+  "account.unblock": "Dadflocio @{name}",
+  "account.unblock_domain": "Dadguddio {domain}",
+  "account.unendorse": "Peidio a'i arddangos ar fy mhroffil",
+  "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",
+  "bundle_column_error.body": "Aeth rhywbeth o'i le tra'n llwytho'r elfen hon.",
+  "bundle_column_error.retry": "Ceisiwch eto",
+  "bundle_column_error.title": "Gwall rhwydwaith",
+  "bundle_modal_error.close": "Cau",
+  "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.direct": "Negeseuon preifat",
+  "column.domain_blocks": "Parthau cuddiedig",
+  "column.favourites": "Ffefrynnau",
+  "column.follow_requests": "Ceisiadau dilyn",
+  "column.home": "Hafan",
+  "column.lists": "Rhestrau",
+  "column.mutes": "Defnyddwyr a ddistewyd",
+  "column.notifications": "Hysbysiadau",
+  "column.pins": "Tŵtiau wedi eu pinio",
+  "column.public": "Ffrwd y ffederasiwn",
+  "column_back_button.label": "Nôl",
+  "column_header.hide_settings": "Cuddio dewisiadau",
+  "column_header.moveLeft_settings": "Symud y golofn i'r chwith",
+  "column_header.moveRight_settings": "Symud y golofn i'r dde",
+  "column_header.pin": "Pinio",
+  "column_header.show_settings": "Dangos gosodiadau",
+  "column_header.unpin": "Dadbinio",
+  "column_subheading.settings": "Gosodiadau",
+  "community.column_settings.media_only": "Cyfryngau yn unig",
+  "compose_form.direct_message_warning": "Mi fydd y tŵt hwn ond yn cael ei anfon at y defnyddwyr sy'n cael eu crybwyll.",
+  "compose_form.direct_message_warning_learn_more": "Dysgu mwy",
+  "compose_form.hashtag_warning": "Ni fydd y tŵt hwn wedi ei restru o dan unrhyw hashnod gan ei fod heb ei restru. Dim ond tŵtiau cyhoeddus gellid chwilota amdanynt drwy hashnod.",
+  "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.publish": "Tŵt",
+  "compose_form.publish_loud": "{publish}!",
+  "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.confirm": "Blocio",
+  "confirmations.block.message": "Ydych chi'n sicr eich bod eisiau blocio {name}?",
+  "confirmations.delete.confirm": "Dileu",
+  "confirmations.delete.message": "Ydych chi'n sicr eich bod eisiau dileu y tŵt hwn?",
+  "confirmations.delete_list.confirm": "Dileu",
+  "confirmations.delete_list.message": "Ydych chi'n sicr eich bod eisiau dileu y rhestr hwn am byth?",
+  "confirmations.domain_block.confirm": "Cuddio parth cyfan",
+  "confirmations.domain_block.message": "A ydych yn hollol, hollol sicr eich bod am flocio y {domain} cyfan? Yn y nifer helaeth o achosion mae blocio neu tawelu ambell gyfrif yn ddigonol ac yn well. Ni fyddwch yn gweld cynnwys o'r parth hwnnw mewn unrhyw ffrydiau cyhoeddus na chwaith yn eich hysbysiadau. Bydd hyn yn cael gwared o'ch dilynwyr o'r parth hwnnw.",
+  "confirmations.mute.confirm": "Tawelu",
+  "confirmations.mute.message": "Ydych chi'n sicr eich bod am ddistewi {name}?",
+  "confirmations.redraft.confirm": "Dileu & ailddrafftio",
+  "confirmations.redraft.message": "Ydych chi'n siwr eich bod eisiau dileu y tŵt hwn a'i ailddrafftio? Bydd ffefrynnau a bwstiau'n cael ei colli, a bydd ymatebion i'r tŵt gwreiddiol yn cael eu hamddifadu.",
+  "confirmations.reply.confirm": "Ateb",
+  "confirmations.reply.message": "Bydd ateb nawr yn cymryd lle y neges yr ydych yn cyfansoddi ar hyn o bryd. Ydych chi'n sicr yr ydych am barhau?",
+  "confirmations.unfollow.confirm": "Dad-ddilynwch",
+  "confirmations.unfollow.message": "Ydych chi'n sicr eich bod am ddad-ddilyn {name}?",
+  "embed.instructions": "Mewnblannwch y tŵt hwn ar eich gwefan drwy gopïo'r côd isod.",
+  "embed.preview": "Dyma sut olwg fydd arno:",
+  "emoji_button.activity": "Gweithgarwch",
+  "emoji_button.custom": "Unigryw",
+  "emoji_button.flags": "Baneri",
+  "emoji_button.food": "Bwyd a Diod",
+  "emoji_button.label": "Mewnosodwch emoji",
+  "emoji_button.nature": "Natur",
+  "emoji_button.not_found": "Dim emojo!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Gwrthrychau",
+  "emoji_button.people": "Pobl",
+  "emoji_button.recent": "Defnyddir yn aml",
+  "emoji_button.search": "Chwilio...",
+  "emoji_button.search_results": "Canlyniadau chwilio",
+  "emoji_button.symbols": "Symbolau",
+  "emoji_button.travel": "Teithio & Llefydd",
+  "empty_column.account_timeline": "No toots here!",
+  "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.",
+  "empty_column.domain_blocks": "Nid oes yna unrhyw barthau cuddiedig eto.",
+  "empty_column.favourited_statuses": "Nid oes gennych unrhyw hoff dwtiau eto. Pan y byddwch yn hoffi un, mi fydd yn ymddangos yma.",
+  "empty_column.favourites": "Nid oes neb wedi hoffi'r tŵt yma eto. Pan bydd rhywun yn ei hoffi, byddent yn ymddangos yma.",
+  "empty_column.follow_requests": "Nid oes gennych unrhyw geisiadau dilyn eto. Pan dderbyniwch chi un, byddent yn ymddangos yma.",
+  "empty_column.hashtag": "Nid oes dim ar yr hashnod hwn eto.",
+  "empty_column.home": "Mae eich ffrwd gartref yn wag! Ymwelwch a {public} neu defnyddiwch y chwilotwr i ddechrau arni ac i gwrdd a defnyddwyr eraill.",
+  "empty_column.home.public_timeline": "y ffrwd gyhoeddus",
+  "empty_column.list": "Nid oes dim yn y rhestr yma eto. Pan y bydd aelodau'r rhestr yn cyhoeddi statws newydd, mi fydd yn ymddangos yma.",
+  "empty_column.lists": "Nid oes gennych unrhyw restrau eto. Pan grëwch chi un, mi fydd yn ymddangos yma.",
+  "empty_column.mutes": "Nid ydych wedi tawelu unrhyw ddefnyddwyr eto.",
+  "empty_column.notifications": "Nid oes gennych unrhyw hysbysiadau eto. Rhyngweithiwch ac eraill i ddechrau'r sgwrs.",
+  "empty_column.public": "Does dim byd yma! Ysgrifennwch rhywbeth yn gyhoeddus, neu dilynwch ddefnyddwyr o achosion eraill i'w lenwi",
+  "follow_request.authorize": "Caniatau",
+  "follow_request.reject": "Gwrthod",
+  "getting_started.developers": "Datblygwyr",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Dogfennaeth",
+  "getting_started.heading": "Dechrau",
+  "getting_started.invite": "Gwahodd pobl",
+  "getting_started.open_source_notice": "Mae Mastodon yn feddalwedd côd agored. Mae modd cyfrannu neu adrodd materion ar GitHUb ar {github}.",
+  "getting_started.security": "Diogelwch",
+  "getting_started.terms": "Telerau Gwasanaeth",
+  "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.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",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "home.column_settings.basic": "Syml",
+  "home.column_settings.show_reblogs": "Dangos bŵstiau",
+  "home.column_settings.show_replies": "Dangos ymatebion",
+  "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.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.reblog.headline": "Hwb",
+  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
+  "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.",
+  "keyboard_shortcuts.back": "i lywio nôl",
+  "keyboard_shortcuts.blocked": "i agor rhestr defnyddwyr a flociwyd",
+  "keyboard_shortcuts.boost": "i fŵstio",
+  "keyboard_shortcuts.column": "i ffocysu tŵt yn un o'r colofnau",
+  "keyboard_shortcuts.compose": "i ffocysu yr ardal cyfansoddi testun",
+  "keyboard_shortcuts.description": "Disgrifiad",
+  "keyboard_shortcuts.direct": "i agor colofn negeseuon preifat",
+  "keyboard_shortcuts.down": "i symud lawr yn y rhestr",
+  "keyboard_shortcuts.enter": "i agor tŵt",
+  "keyboard_shortcuts.favourite": "i hoffi",
+  "keyboard_shortcuts.favourites": "i agor rhestr hoffi",
+  "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.legend": "i ddangos yr arwr yma",
+  "keyboard_shortcuts.local": "i agor ffrwd lleol",
+  "keyboard_shortcuts.mention": "i grybwyll yr awdur",
+  "keyboard_shortcuts.muted": "i agor rhestr defnyddwyr a dawelwyd",
+  "keyboard_shortcuts.my_profile": "i agor eich proffil",
+  "keyboard_shortcuts.notifications": "i agor colofn hysbysiadau",
+  "keyboard_shortcuts.pinned": "i agor rhestr tŵtiau wedi'i pinio",
+  "keyboard_shortcuts.profile": "i agor proffil yr awdur",
+  "keyboard_shortcuts.reply": "i ateb",
+  "keyboard_shortcuts.requests": "i agor rhestr ceisiadau dilyn",
+  "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.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",
+  "lists.account.add": "Ychwanegwch at restr",
+  "lists.account.remove": "Dileu o'r rhestr",
+  "lists.delete": "Dileu rhestr",
+  "lists.edit": "Golygwch rhestr",
+  "lists.new.create": "Ychwanegu rhestr",
+  "lists.new.title_placeholder": "Teitl rhestr newydd",
+  "lists.search": "Chwilio ymysg pobl yr ydych yn ei ddilyn",
+  "lists.subheading": "Eich rhestrau",
+  "loading_indicator.label": "Llwytho...",
+  "media_gallery.toggle_visible": "Toglo gwelededd",
+  "missing_indicator.label": "Heb ei ganfod",
+  "missing_indicator.sublabel": "Ni ellid canfod yr adnodd hwn",
+  "mute_modal.hide_notifications": "Cuddio hysbysiadau rhag y defnyddiwr hwn?",
+  "navigation_bar.apps": "Apiau symudol",
+  "navigation_bar.blocks": "Defnyddwyr wedi eu blocio",
+  "navigation_bar.community_timeline": "Ffrwd leol",
+  "navigation_bar.compose": "Cyfansoddi tŵt newydd",
+  "navigation_bar.direct": "Negeseuon preifat",
+  "navigation_bar.discover": "Darganfod",
+  "navigation_bar.domain_blocks": "Parthau cuddiedig",
+  "navigation_bar.edit_profile": "Golygu proffil",
+  "navigation_bar.favourites": "Ffefrynnau",
+  "navigation_bar.filters": "Geiriau a dawelwyd",
+  "navigation_bar.follow_requests": "Ceisiadau dilyn",
+  "navigation_bar.info": "Ynghylch yr achos hwn",
+  "navigation_bar.keyboard_shortcuts": "Bysellau brys",
+  "navigation_bar.lists": "Rhestrau",
+  "navigation_bar.logout": "Allgofnodi",
+  "navigation_bar.mutes": "Defnyddwyr a dawelwyd",
+  "navigation_bar.personal": "Personol",
+  "navigation_bar.pins": "Tŵtiau wedi eu pinio",
+  "navigation_bar.preferences": "Dewisiadau",
+  "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.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.show": "Dangos",
+  "notifications.column_settings.follow": "Dilynwyr newydd:",
+  "notifications.column_settings.mention": "Crybwylliadau:",
+  "notifications.column_settings.push": "Hysbysiadau push",
+  "notifications.column_settings.reblog": "Hybiadau:",
+  "notifications.column_settings.show": "Dangos yn y golofn",
+  "notifications.column_settings.sound": "Chwarae sain",
+  "notifications.filter.all": "Pob",
+  "notifications.filter.boosts": "Hybiadau",
+  "notifications.filter.favourites": "Ffefrynnau",
+  "notifications.filter.follows": "Yn dilyn",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.group": "{count} o hysbysiadau",
+  "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",
+  "privacy.private.long": "Cyhoeddi i ddilynwyr yn unig",
+  "privacy.private.short": "Dilynwyr-yn-unig",
+  "privacy.public.long": "Cyhoeddi i ffrydiau cyhoeddus",
+  "privacy.public.short": "Cyhoeddus",
+  "privacy.unlisted.long": "Peidio a chyhoeddi i ffrydiau cyhoeddus",
+  "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.just_now": "nawr",
+  "relative_time.minutes": "{number}m",
+  "relative_time.seconds": "{number}s",
+  "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?",
+  "report.hint": "Bydd yr adroddiad yn cael ei anfon i arolygydd eich achos. Mae modd darparu esboniad o pam yr ydych yn cwyno am y cyfrif hwn isod:",
+  "report.placeholder": "Sylwadau ychwanegol",
+  "report.submit": "Cyflwyno",
+  "report.target": "Cwyno am {target}",
+  "search.placeholder": "Chwilio",
+  "search_popout.search_format": "Fformat chwilio uwch",
+  "search_popout.tips.full_text": "Mae testun syml yn dychwelyd tŵtiau yr ydych wedi ysgrifennu, hoffi, wedi'u bŵstio, neu wedi'ch crybwyll ynddynt, ynghyd a chyfateb a enwau defnyddwyr, enwau arddangos ac hashnodau.",
+  "search_popout.tips.hashtag": "hashnod",
+  "search_popout.tips.status": "tŵt",
+  "search_popout.tips.text": "Mae testun syml yn dychwelyd enwau arddangos, enwau defnyddwyr a hashnodau sy'n cyfateb",
+  "search_popout.tips.user": "defnyddiwr",
+  "search_results.accounts": "Pobl",
+  "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.block": "Blocio @{name}",
+  "status.cancel_reblog_private": "Dadfŵstio",
+  "status.cannot_reblog": "Ni ellir sbarduno'r tŵt hwn",
+  "status.delete": "Dileu",
+  "status.detailed_status": "Golwg manwl o'r sgwrs",
+  "status.direct": "Neges breifat @{name}",
+  "status.embed": "Plannu",
+  "status.favourite": "Hoffi",
+  "status.filtered": "Wedi'i hidlo",
+  "status.load_more": "Llwythwch mwy",
+  "status.media_hidden": "Cyfryngau wedi'u cuddio",
+  "status.mention": "Crybwyll @{name}",
+  "status.more": "Mwy",
+  "status.mute": "Tawelu @{name}",
+  "status.mute_conversation": "Tawelu sgwrs",
+  "status.open": "Ehangu'r tŵt hwn",
+  "status.pin": "Pinio ar y proffil",
+  "status.pinned": "Pinio tŵt",
+  "status.read_more": "Darllen mwy",
+  "status.reblog": "Hybu",
+  "status.reblog_private": "Hybu i'r gynulleidfa wreiddiol",
+  "status.reblogged_by": "Bŵstio {name}",
+  "status.reblogs.empty": "Does neb wedi bŵstio'r tŵt yma eto. Pan y bydd rhywun yn gwneud, byddent yn ymddangos yma.",
+  "status.redraft": "Dileu & ailddrafftio",
+  "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",
+  "status.show_less_all": "Dangos llai i bawb",
+  "status.show_more": "Dangos mwy",
+  "status.show_more_all": "Dangos mwy i bawb",
+  "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…",
+  "tabs_bar.federated_timeline": "Ffederasiwn",
+  "tabs_bar.home": "Hafan",
+  "tabs_bar.local_timeline": "Lleol",
+  "tabs_bar.notifications": "Hysbysiadau",
+  "tabs_bar.search": "Chwilio",
+  "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_form.description": "Disgrifio i'r rheini a nam ar ei golwg",
+  "upload_form.focus": "Newid rhagolwg",
+  "upload_form.undo": "Dileu",
+  "upload_progress.label": "Uwchlwytho...",
+  "video.close": "Cau fideo",
+  "video.exit_fullscreen": "Gadael sgrîn llawn",
+  "video.expand": "Ymestyn fideo",
+  "video.fullscreen": "Sgrîn llawn",
+  "video.hide": "Cuddio fideo",
+  "video.mute": "Tawelu sain",
+  "video.pause": "Oedi",
+  "video.play": "Chwarae",
+  "video.unmute": "Dad-dawelu sain"
+}
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 37b5e73ee77e53555e8f528c9232524821706dfd..60315211adfdd51ddcc03695e16b7ea488e86e66 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Tilføj eller fjern fra lister",
   "account.badges.bot": "Robot",
   "account.block": "Bloker @{name}",
   "account.block_domain": "Skjul alt fra {domain}",
@@ -7,25 +8,31 @@
   "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",
   "account.follow": "Følg",
   "account.followers": "Følgere",
+  "account.followers.empty": "Der er endnu ingen der følger denne bruger.",
   "account.follows": "Følger",
+  "account.follows.empty": "Denne bruger følger endnu ikke nogen.",
   "account.follows_you": "Følger dig",
   "account.hide_reblogs": "Skjul fremhævelserne fra @{name}",
-  "account.media": "Multimedier",
+  "account.link_verified_on": "Ejerskabet af dette link blev tjekket den %{date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.media": "Medie",
   "account.mention": "Nævn @{name}",
   "account.moved_to": "{name} er flyttet til:",
   "account.mute": "Dæmp @{name}",
   "account.mute_notifications": "Dæmp notifikationer fra @{name}",
   "account.muted": "Dæmpet",
-  "account.posts": "Dyt",
-  "account.posts_with_replies": "Toots og svar",
+  "account.posts": "Trut",
+  "account.posts_with_replies": "Trut og svar",
   "account.report": "Rapporter @{name}",
   "account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning",
   "account.share": "Del @{name}s profil",
   "account.show_reblogs": "Vis fremhævelserne fra @{name}",
   "account.unblock": "Fjern blokeringen af @{name}",
   "account.unblock_domain": "Skjul ikke længere {domain}",
+  "account.unendorse": "Fremhæv ikke på profil",
   "account.unfollow": "Følg ikke længere",
   "account.unmute": "Fjern dæmpningen af @{name}",
   "account.unmute_notifications": "Fjern dæmpningen af notifikationer fra @{name}",
@@ -49,7 +56,7 @@
   "column.lists": "Lister",
   "column.mutes": "Dæmpede brugere",
   "column.notifications": "Notifikationer",
-  "column.pins": "Fastgjorte toots",
+  "column.pins": "Fastgjorte trut",
   "column.public": "Fælles tidslinje",
   "column_back_button.label": "Tilbage",
   "column_header.hide_settings": "Skjul indstillinger",
@@ -59,7 +66,7 @@
   "column_header.show_settings": "Vis indstillinger",
   "column_header.unpin": "Fastgør ikke længere",
   "column_subheading.settings": "Indstillinger",
-  "community.column_settings.media_only": "Kun multimedier",
+  "community.column_settings.media_only": "Kun medie",
   "compose_form.direct_message_warning": "Dette trut vil kun blive sendt til de nævnte brugere.",
   "compose_form.direct_message_warning_learn_more": "Lær mere",
   "compose_form.hashtag_warning": "Dette trut vil ikke blive vist under noget hashtag da det ikke er listet. Kun offentlige trut kan blive vist under søgninger med hashtags.",
@@ -68,8 +75,8 @@
   "compose_form.placeholder": "Hvad har du på hjertet?",
   "compose_form.publish": "Trut",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Multimedie er markeret som værende følsomt",
-  "compose_form.sensitive.unmarked": "Multimediet er ikke markeret som værende følsomt",
+  "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",
@@ -81,11 +88,13 @@
   "confirmations.delete_list.confirm": "Slet",
   "confirmations.delete_list.message": "Er du sikker på, du vil slette denne liste?",
   "confirmations.domain_block.confirm": "Skjul helt domæne",
-  "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.domain_block.message": "Er du helt sikker på du vil blokere hele {domain} domænet? I de fleste tilfælde vil få specifikke blokeringer eller dæmpninger være nok og at fortrække. Du vil ikke se indhold fra det domæne hverken på offentlige tidslinjer eller i dine notifikationer. Dine følgere fra det domæne vil blive fjernet.",
   "confirmations.mute.confirm": "Dæmp",
   "confirmations.mute.message": "Er du sikker på, du vil dæmpe {name}?",
   "confirmations.redraft.confirm": "Slet & omskriv",
-  "confirmations.redraft.message": "Er du sikker på, du vil slette denne status og omskrive den? Du vil miste alle svar, fremhævelser og favoritter der medfølger.",
+  "confirmations.redraft.message": "Er du sikker på, du vil slette denne status og omskrive den? Favoritter og fremhævelser vil gå tabt og svar til det oprindelige opslag vil blive forældreløse.",
+  "confirmations.reply.confirm": "Svar",
+  "confirmations.reply.message": "Hvis du svarer nu vil du overskrive den besked du er ved at skrive. Er du sikker på, du vil fortsætte?",
   "confirmations.unfollow.confirm": "Følg ikke længere",
   "confirmations.unfollow.message": "Er du sikker på, du ikke længere vil følge {name}?",
   "embed.instructions": "Indlejre denne status på din side ved at kopiere nedenstående kode.",
@@ -101,44 +110,89 @@
   "emoji_button.people": "Mennesker",
   "emoji_button.recent": "Oftest brugt",
   "emoji_button.search": "Søg...",
-  "emoji_button.search_results": "Søgeresultat",
+  "emoji_button.search_results": "Søgeresultater",
   "emoji_button.symbols": "Symboler",
   "emoji_button.travel": "Rejser & steder",
+  "empty_column.account_timeline": "No toots here!",
+  "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.",
+  "empty_column.domain_blocks": "Der er endnu ikke nogle skjulte domæner.",
+  "empty_column.favourited_statuses": "Du har endnu ikke favoriseret nogen trut. NÃ¥r du favoriserer et, vil det blive vist her.",
+  "empty_column.favourites": "Endnu ingen har favoriseret dette trut. Når en anden gør vil det blive vist her.",
+  "empty_column.follow_requests": "Du har endnu ingen følgeranmodninger. Når du modtager en, vil den komme frem her.",
   "empty_column.hashtag": "Dette hashtag indeholder endnu ikke noget.",
   "empty_column.home": "Din hjemme tidslinje er tom! Besøg {public} eller brug søgningen for at komme igang og møde andre brugere.",
   "empty_column.home.public_timeline": "den offentlige tidslinje",
   "empty_column.list": "Der er endnu intet i denne liste. NÃ¥r medlemmer af denne liste poster nye statusser, vil de vises her.",
+  "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",
   "follow_request.authorize": "Godkend",
   "follow_request.reject": "Afvis",
   "getting_started.developers": "Udviklere",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Dokumentation",
-  "getting_started.find_friends": "Find venner fra Twitter",
   "getting_started.heading": "Kom igang",
   "getting_started.invite": "Inviter folk",
   "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_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": "Grundlæggende",
   "home.column_settings.show_reblogs": "Vis fremhævelser",
   "home.column_settings.show_replies": "Vis svar",
+  "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.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": "for at navigere dig tilbage",
+  "keyboard_shortcuts.blocked": "for at åbne listen over blokerede brugere",
   "keyboard_shortcuts.boost": "for at fremhæve",
   "keyboard_shortcuts.column": "for at fokusere på en status i en af kolonnerne",
   "keyboard_shortcuts.compose": "for at fokusere på skriveområdet",
   "keyboard_shortcuts.description": "Beskrivelse",
+  "keyboard_shortcuts.direct": "for at åbne privat besked kolonnen",
   "keyboard_shortcuts.down": "for at rykke ned ad listen",
   "keyboard_shortcuts.enter": "for at åbne status",
   "keyboard_shortcuts.favourite": "for at favorisere",
+  "keyboard_shortcuts.favourites": "for at åbne listen over favoritter",
+  "keyboard_shortcuts.federated": "for at åbne den forenede tidslinje",
   "keyboard_shortcuts.heading": "Tastaturgenveje",
+  "keyboard_shortcuts.home": "for at åbne hjem tidslinjen",
   "keyboard_shortcuts.hotkey": "Hurtigtast",
   "keyboard_shortcuts.legend": "for at vise denne legende",
+  "keyboard_shortcuts.local": "for at åbne den lokale tidslinje",
   "keyboard_shortcuts.mention": "for at nævne forfatteren",
+  "keyboard_shortcuts.muted": "for at åbne listen over dæmpede brugere",
+  "keyboard_shortcuts.my_profile": "for at åbne din profil",
+  "keyboard_shortcuts.notifications": "for at åbne notifikations kolonnen",
+  "keyboard_shortcuts.pinned": "for at åbne listen over fastgjorte trut",
+  "keyboard_shortcuts.profile": "til profil af åben forfatter",
   "keyboard_shortcuts.reply": "for at svare",
+  "keyboard_shortcuts.requests": "for at åbne listen over følgeranmodninger",
   "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.toot": "for at påbegynde et helt nyt trut",
   "keyboard_shortcuts.unfocus": "for at fjerne fokus fra skriveområde/søgning",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Ikke fundet",
   "missing_indicator.sublabel": "Denne ressource kunne ikke blive fundet",
   "mute_modal.hide_notifications": "Skjul notifikationer fra denne bruger?",
+  "navigation_bar.apps": "Mobil apps",
   "navigation_bar.blocks": "Blokerede brugere",
   "navigation_bar.community_timeline": "Lokal tidslinje",
+  "navigation_bar.compose": "Skriv nyt trut",
   "navigation_bar.direct": "Direkte beskeder",
   "navigation_bar.discover": "Opdag",
   "navigation_bar.domain_blocks": "Skjulte domæner",
   "navigation_bar.edit_profile": "Rediger profil",
   "navigation_bar.favourites": "Favoritter",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Dæmpede ord",
   "navigation_bar.follow_requests": "Følgeanmodninger",
   "navigation_bar.info": "Om denne instans",
   "navigation_bar.keyboard_shortcuts": "Hurtigtast",
@@ -174,8 +230,8 @@
   "navigation_bar.logout": "Logud",
   "navigation_bar.mutes": "Dæmpede brugere",
   "navigation_bar.personal": "Personligt",
-  "navigation_bar.pins": "Fastgjorte toots",
-  "navigation_bar.preferences": "Indstillinger",
+  "navigation_bar.pins": "Fastgjorte trut",
+  "navigation_bar.preferences": "Præferencer",
   "navigation_bar.public_timeline": "Fælles tidslinje",
   "navigation_bar.security": "Sikkerhed",
   "notification.favourite": "{name} favoriserede din status",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Er du sikker på, du vil rydde alle dine notifikationer permanent?",
   "notifications.column_settings.alert": "Skrivebords notifikationer",
   "notifications.column_settings.favourite": "Favoritter:",
+  "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": "Nye følgere:",
   "notifications.column_settings.mention": "Omtale:",
   "notifications.column_settings.push": "Push notifikationer",
-  "notifications.column_settings.push_meta": "Denne enhed",
   "notifications.column_settings.reblog": "Fremhævelser:",
   "notifications.column_settings.show": "Vis i kolonne",
   "notifications.column_settings.sound": "Afspil lyd",
+  "notifications.filter.all": "Alle",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favoritter",
+  "notifications.filter.follows": "Følger",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifikationer",
-  "onboarding.done": "Færdig",
-  "onboarding.next": "Næste",
-  "onboarding.page_five.public_timelines": "Den lokale tidslinje viser offentlige opslag fra alle i {domain}. Den fælles tidslinje viser opslag fra alle der følges af folk i {domain}. Disse er de offentlige tidslinjer, hvilket er en god måde at møde nye mennesker på.",
-  "onboarding.page_four.home": "Hjem tidslinjen viser opslag fra folk som du følger.",
-  "onboarding.page_four.notifications": "Notifikations kolonnen viser når nogen interagerer med dig.",
-  "onboarding.page_one.federation": "Mastodon er et netværk af uafhængige serverer der forbindes til at udgøre et større socialt netværk. Vi kalder disse servere for instanser.",
-  "onboarding.page_one.full_handle": "Dit fulde brugernavn",
-  "onboarding.page_one.handle_hint": "Dette er hvad du vil fortælle dine venner hvad de skal søge efter.",
-  "onboarding.page_one.welcome": "Velkommen til Mastodon!",
-  "onboarding.page_six.admin": "Administratoren for denne instans er {admin}.",
-  "onboarding.page_six.almost_done": "Næsten færdig...",
-  "onboarding.page_six.appetoot": "God Appetoot!",
-  "onboarding.page_six.apps_available": "Der er {apps} tilgængelige for iOS, Android og andre platforme.",
-  "onboarding.page_six.github": "Mastodon er frit open-source software. Du kan rapportere fejl, anmode om features, eller bidrage til koden ved at gå til {github}.",
-  "onboarding.page_six.guidelines": "retningslinjer for fællesskabet",
-  "onboarding.page_six.read_guidelines": "Læs venligst {domain}s {guidelines}!",
-  "onboarding.page_six.various_app": "apps til mobilen",
-  "onboarding.page_three.profile": "Rediger din profil for at ændre profilbillede, beskrivelse og visningsnavn. Der vil du også finde andre indstillinger.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Spring over",
   "privacy.change": "Ændre status privatliv",
   "privacy.direct.long": "Post til kun de nævnte brugere",
   "privacy.direct.short": "Direkte",
@@ -240,26 +282,29 @@
   "report.target": "Anmelder {target}",
   "search.placeholder": "Søg",
   "search_popout.search_format": "Avanceret søgeformat",
-  "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": "Simpel tekst returnerer statusser du har skrevet, favoriseret, fremhævet, eller er blevet nævnt i, lige så vel som matchende brugernavne, visningsnavne, og hashtags.",
   "search_popout.tips.hashtag": "emnetag",
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simpelt tekst returnerer passende visningsnavne, brugernavne og hashtags",
   "search_popout.tips.user": "bruger",
   "search_results.accounts": "Folk",
   "search_results.hashtags": "Emnetags",
-  "search_results.statuses": "Toote",
+  "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.delete": "Slet",
+  "status.detailed_status": "Detaljeret visning af samtale",
   "status.direct": "Send direkte besked til @{name}",
   "status.embed": "Indlejre",
   "status.favourite": "Favorit",
   "status.filtered": "Filtreret",
   "status.load_more": "Indlæs mere",
-  "status.media_hidden": "Multimedia skjult",
+  "status.media_hidden": "Medie skjult",
   "status.mention": "Nævn @{name}",
   "status.more": "Mere",
   "status.mute": "Dæmp @{name}",
@@ -267,12 +312,14 @@
   "status.open": "Udvid denne status",
   "status.pin": "Fastgør til profil",
   "status.pinned": "Fastgjort trut",
+  "status.read_more": "Læs mere",
   "status.reblog": "Fremhæv",
   "status.reblog_private": "Fremhæv til oprindeligt publikum",
   "status.reblogged_by": "{name} fremhævede",
+  "status.reblogs.empty": "Der er endnu ingen der har fremhævet dette trut. Når der er nogen der gør, vil det blive vist her.",
   "status.redraft": "Slet og omskriv",
   "status.reply": "Svar",
-  "status.replyAll": "Svar tråd",
+  "status.replyAll": "Svar samtale",
   "status.report": "Anmeld @{name}",
   "status.sensitive_toggle": "Tryk for at se",
   "status.sensitive_warning": "Følsomt indhold",
@@ -281,18 +328,21 @@
   "status.show_less_all": "Vis mindre for alle",
   "status.show_more": "Vis mere",
   "status.show_more_all": "Vis mere for alle",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Fjern dæmpningen fra samtale",
   "status.unpin": "Fjern som fastgjort fra profil",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Fælles",
   "tabs_bar.home": "Hjem",
   "tabs_bar.local_timeline": "Lokal",
   "tabs_bar.notifications": "Notifikationer",
   "tabs_bar.search": "Søg",
-  "trends.count_by_accounts": "{count} {rawCount, flere, en {person} flere {people}} snakker",
+  "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 multimedier",
-  "upload_form.description": "Beskrivelse for de svagtseende",
+  "upload_button.label": "Tilføj medie (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_form.description": "Beskriv for de svagtseende",
   "upload_form.focus": "Beskær",
   "upload_form.undo": "Slet",
   "upload_progress.label": "Uploader...",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 8ea318158aca5dec75d72d44fd37b20cfc5bac1d..3a55f26a7521d933085a2299488e1ea453ae009b 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -1,17 +1,23 @@
 {
+  "account.add_or_remove_from_list": "Hinzufügen oder Entfernen von Listen",
   "account.badges.bot": "Bot",
-  "account.block": "@{name} blocken",
+  "account.block": "@{name} blockieren",
   "account.block_domain": "Alles von {domain} verstecken",
   "account.blocked": "Blockiert",
-  "account.direct": "Direct Message @{name}",
+  "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.empty": "Diesem Profil folgt noch niemand.",
   "account.follows": "Folgt",
+  "account.follows.empty": "Dieses Profil folgt noch niemandem.",
   "account.follows_you": "Folgt dir",
   "account.hide_reblogs": "Geteilte Beiträge von @{name} verbergen",
+  "account.link_verified_on": "Besitz dieses Links wurde geprüft am {date}",
+  "account.locked_info": "Der Privatsphärenstatus dieses Accounts wurde auf gesperrt gesetzt. Die Person bestimmt manuell wer ihm/ihr folgen darf.",
   "account.media": "Medien",
   "account.mention": "@{name} erwähnen",
   "account.moved_to": "{name} ist umgezogen auf:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Von @{name} geteilte Beiträge anzeigen",
   "account.unblock": "@{name} entblocken",
   "account.unblock_domain": "{domain} wieder anzeigen",
+  "account.unendorse": "Nicht auf Profil hervorheben",
   "account.unfollow": "Entfolgen",
   "account.unmute": "@{name} nicht mehr stummschalten",
   "account.unmute_notifications": "Benachrichtigungen von @{name} einschalten",
@@ -65,7 +72,7 @@
   "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.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.placeholder": "Was gibt's Neues?",
   "compose_form.publish": "Tröt",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.marked": "Medien sind als heikel markiert",
@@ -81,11 +88,13 @@
   "confirmations.delete_list.confirm": "Delete",
   "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} verbergen willst? In den meisten Fällen reichen ein paar gezielte Blocks aus. Du wirst nicht den Inhalt von dieser Domain 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. Du wirst den Inhalt von dieser Domain nicht in irgendwelchen öffentlichen Timelines oder den Benachrichtigungen finden. Deine Follower von dieser Domain werden 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 Status löschen und neu machen möchtest? Du wirst alle Antworten, Boosts und Favoriten darauf verlieren.",
+  "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.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",
   "confirmations.unfollow.message": "Bist du dir sicher, dass du {name} entfolgen möchtest?",
   "embed.instructions": "Du kannst diesen Beitrag auf deiner Webseite einbetten, indem du den folgenden Code einfügst.",
@@ -104,44 +113,89 @@
   "emoji_button.search_results": "Suchergebnisse",
   "emoji_button.symbols": "Symbole",
   "emoji_button.travel": "Reisen und Orte",
+  "empty_column.account_timeline": "Keine Beiträge!",
+  "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.",
+  "empty_column.domain_blocks": "Es ist noch keine versteckten Domains.",
+  "empty_column.favourited_statuses": "Du hast noch keine favorisierten Tröts. Wenn du einen favorisierst, wird er hier erscheinen.",
+  "empty_column.favourites": "Noch niemand hat diesen Beitrag favorisiert. Sobald es jemand tut, wird das hier angezeigt.",
+  "empty_column.follow_requests": "Du hast noch keine Folge-Anfragen. Sobald du eine erhältst, wird sie hier angezeigt.",
   "empty_column.hashtag": "Unter diesem Hashtag gibt es noch nichts.",
   "empty_column.home": "Deine Startseite ist leer! Besuche {public} oder nutze die Suche, um loszulegen und andere Leute zu finden.",
   "empty_column.home.public_timeline": "die öffentliche Zeitleiste",
   "empty_column.list": "Diese Liste ist derzeit leer. Wenn Wesen auf dieser Liste neue Beiträge veröffentlichen werden sie hier erscheinen.",
+  "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",
   "follow_request.authorize": "Erlauben",
   "follow_request.reject": "Ablehnen",
   "getting_started.developers": "Entwickler",
-  "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Finde Freunde von Twitter",
+  "getting_started.directory": "Profilverzeichnis",
+  "getting_started.documentation": "Dokumentation",
   "getting_started.heading": "Erste Schritte",
   "getting_started.invite": "Leute einladen",
   "getting_started.open_source_notice": "Mastodon ist quelloffene Software. Du kannst auf GitHub unter {github} dazu beitragen oder Probleme melden.",
   "getting_started.security": "Sicherheit",
   "getting_started.terms": "Nutzungsbedingungen",
+  "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.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",
   "home.column_settings.basic": "Einfach",
   "home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen",
   "home.column_settings.show_replies": "Antworten anzeigen",
+  "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.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.reblog.headline": "Teilen",
+  "introduction.interactions.reblog.text": "Du kannst Beiträge von anderen Leuten an deine Follower teilen.",
+  "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.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.",
   "keyboard_shortcuts.back": "zurück navigieren",
-  "keyboard_shortcuts.boost": "boosten",
+  "keyboard_shortcuts.blocked": "Liste blockierter Profile öffnen",
+  "keyboard_shortcuts.boost": "teilen",
   "keyboard_shortcuts.column": "einen Status in einer der Spalten fokussieren",
-  "keyboard_shortcuts.compose": "um das Textfeld zu 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": "um den Status zu öffnen",
+  "keyboard_shortcuts.enter": "Status öffnen",
   "keyboard_shortcuts.favourite": "um zu favorisieren",
+  "keyboard_shortcuts.favourites": "Favoriten-Liste öffnen",
+  "keyboard_shortcuts.federated": "Förderierte Zeitleiste öffnen",
   "keyboard_shortcuts.heading": "Tastenkombinationen",
+  "keyboard_shortcuts.home": "Startseite öffnen",
   "keyboard_shortcuts.hotkey": "Tastenkürzel",
-  "keyboard_shortcuts.legend": "um diese Übersicht anzuzeigen",
+  "keyboard_shortcuts.legend": "diese Übersicht anzeigen",
+  "keyboard_shortcuts.local": "Lokale Zeitleiste öffnen",
   "keyboard_shortcuts.mention": "um Autor_in zu erwähnen",
-  "keyboard_shortcuts.reply": "um zu antworten",
-  "keyboard_shortcuts.search": "um die Suche zu fokussieren",
-  "keyboard_shortcuts.toggle_hidden": "um den Text hinter einer Inhaltswarnung zu verstecken oder ihn anzuzeigen",
-  "keyboard_shortcuts.toot": "um einen neuen Toot zu beginnen",
-  "keyboard_shortcuts.unfocus": "um das Textfeld/die Suche nicht mehr zu fokussieren",
+  "keyboard_shortcuts.muted": "Liste stummgeschalteter Profile öffnen",
+  "keyboard_shortcuts.my_profile": "Dein Profil öffnen",
+  "keyboard_shortcuts.notifications": "Benachrichtigungsspalte öffnen",
+  "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.search": "Suche fokussieren",
+  "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.unfocus": "Textfeld/die Suche nicht mehr fokussieren",
   "keyboard_shortcuts.up": "sich in der Liste hinauf bewegen",
   "lightbox.close": "Schließen",
   "lightbox.next": "Weiter",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Nicht gefunden",
   "missing_indicator.sublabel": "Die Ressource konnte nicht gefunden werden",
   "mute_modal.hide_notifications": "Benachrichtigungen von diesem Account verbergen?",
+  "navigation_bar.apps": "Mobile Apps",
   "navigation_bar.blocks": "Blockierte Profile",
   "navigation_bar.community_timeline": "Lokale Zeitleiste",
+  "navigation_bar.compose": "Neuen Beitrag verfassen",
   "navigation_bar.direct": "Direktnachrichten",
   "navigation_bar.discover": "Entdecken",
   "navigation_bar.domain_blocks": "Versteckte Domains",
   "navigation_bar.edit_profile": "Profil bearbeiten",
   "navigation_bar.favourites": "Favoriten",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Stummgeschaltene Wörter",
   "navigation_bar.follow_requests": "Folgeanfragen",
   "navigation_bar.info": "Über diese Instanz",
   "navigation_bar.keyboard_shortcuts": "Tastenkombinationen",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Bist du dir sicher, dass du alle Mitteilungen löschen möchtest?",
   "notifications.column_settings.alert": "Desktop-Benachrichtigungen",
   "notifications.column_settings.favourite": "Favorisierungen:",
+  "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.mention": "Erwähnungen:",
   "notifications.column_settings.push": "Push-Benachrichtigungen",
-  "notifications.column_settings.push_meta": "Auf diesem Gerät",
   "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.mentions": "Erwähnungen",
   "notifications.group": "{count} Benachrichtigungen",
-  "onboarding.done": "Fertig",
-  "onboarding.next": "Weiter",
-  "onboarding.page_five.public_timelines": "Die lokale Zeitleiste zeigt alle Beiträge von Leuten, die auch auf {domain} sind. Das gesamte bekannte Netz zeigt Beiträge von allen, denen von Leuten auf {domain} gefolgt wird. Zusammen sind sie die öffentlichen Zeitleisten, ein guter Weg, um neue Leute zu finden.",
-  "onboarding.page_four.home": "Die Startseite zeigt dir Beiträge von Leuten, denen du folgst.",
-  "onboarding.page_four.notifications": "Wenn jemand mit dir interagiert, bekommst du eine Mitteilung.",
-  "onboarding.page_one.federation": "Mastodon ist ein soziales Netzwerk, das aus unabhängigen Servern besteht. Diese Server nennen wir auch Instanzen.",
-  "onboarding.page_one.full_handle": "Dein vollständiger Benutzername",
-  "onboarding.page_one.handle_hint": "Das ist das, was du deinen Freunden sagst, um nach dir zu suchen.",
-  "onboarding.page_one.welcome": "Willkommen bei Mastodon!",
-  "onboarding.page_six.admin": "Für deine Instanz ist {admin} zuständig.",
-  "onboarding.page_six.almost_done": "Fast fertig …",
-  "onboarding.page_six.appetoot": "Guten Appetröt!",
-  "onboarding.page_six.apps_available": "Es gibt verschiedene {apps} für iOS, Android und weitere Plattformen.",
-  "onboarding.page_six.github": "Mastodon ist freie, quelloffene Software. Du kannst auf {github} dazu beitragen, Probleme melden und Wünsche äußern.",
-  "onboarding.page_six.guidelines": "Richtlinien",
-  "onboarding.page_six.read_guidelines": "Bitte mach dich mit den {guidelines} von {domain} vertraut!",
-  "onboarding.page_six.various_app": "Apps",
-  "onboarding.page_three.profile": "Bearbeite dein Profil, um dein Bild, deinen Namen und deine Beschreibung anzupassen. Dort findest du auch weitere Einstellungen.",
-  "onboarding.page_three.search": "Benutze die Suchfunktion, um Leute zu finden und mit Hashtags wie {illustration} oder {introductions} nach Beiträgen zu suchen. Um eine Person zu finden, die auf einer anderen Instanz ist, benutze den vollständigen Profilnamen.",
-  "onboarding.page_two.compose": "Schreibe deine Beiträge in der Schreiben-Spalte. Mit den Symbolen unter dem Eingabefeld kannst du Bilder hochladen, Sichtbarkeits-Einstellungen ändern und Inhaltswarnungen hinzufügen.",
-  "onboarding.skip": "Überspringen",
   "privacy.change": "Sichtbarkeit des Beitrags anpassen",
   "privacy.direct.long": "Beitrag nur an erwähnte Profile",
   "privacy.direct.short": "Direkt",
@@ -250,10 +292,13 @@
   "search_results.statuses": "Beiträge",
   "search_results.total": "{count, number} {count, plural, one {Ergebnis} other {Ergebnisse}}",
   "standalone.public_title": "Ein kleiner Einblick …",
-  "status.block": "Block @{name}",
+  "status.admin_account": "Öffne Moderationsoberfläche für @{name}",
+  "status.admin_status": "Öffne diesen Status 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.delete": "Löschen",
+  "status.detailed_status": "Detaillierte Ansicht der Konversation",
   "status.direct": "Direktnachricht @{name}",
   "status.embed": "Einbetten",
   "status.favourite": "Favorisieren",
@@ -267,9 +312,11 @@
   "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.reblogged_by": "{name} teilte",
+  "status.reblogs.empty": "Diesen Beitrag hat noch niemand geteilt. Sobald es jemand tut, wird die Person hier angezeigt.",
   "status.redraft": "Löschen und neu erstellen",
   "status.reply": "Antworten",
   "status.replyAll": "Auf Thread antworten",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Zeige weniger für alles",
   "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.unpin": "Vom Profil lösen",
+  "suggestions.dismiss": "Hinweis ausblenden",
+  "suggestions.header": "Du bist vielleicht interessiert in…",
   "tabs_bar.federated_timeline": "Föderation",
   "tabs_bar.home": "Startseite",
   "tabs_bar.local_timeline": "Lokal",
@@ -291,9 +341,9 @@
   "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",
+  "upload_button.label": "Mediendatei hinzufügen (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Für Menschen mit Sehbehinderung beschreiben",
-  "upload_form.focus": "Zuschneiden",
+  "upload_form.focus": "Thumbnail bearbeiten",
   "upload_form.undo": "Löschen",
   "upload_progress.label": "Wird hochgeladen …",
   "video.close": "Video schließen",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 8c43b4f42ef5e52c9b3a3fc018f24edc64261a54..6ac8160ba4dc5ec3d78c82f6ed78995a7e74f4ef 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -302,12 +302,24 @@
       {
         "defaultMessage": "Embed",
         "id": "status.embed"
+      },
+      {
+        "defaultMessage": "Open moderation interface for @{name}",
+        "id": "status.admin_account"
+      },
+      {
+        "defaultMessage": "Open this status in the moderation interface",
+        "id": "status.admin_status"
       }
     ],
     "path": "app/javascript/mastodon/components/status_action_bar.json"
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Read more",
+        "id": "status.read_more"
+      },
       {
         "defaultMessage": "Show more",
         "id": "status.show_more"
@@ -345,6 +357,10 @@
       {
         "defaultMessage": "{name} boosted",
         "id": "status.reblogged_by"
+      },
+      {
+        "defaultMessage": "Show thread",
+        "id": "status.show_thread"
       }
     ],
     "path": "app/javascript/mastodon/components/status.json"
@@ -390,13 +406,21 @@
         "id": "confirmations.redraft.confirm"
       },
       {
-        "defaultMessage": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+        "defaultMessage": "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.",
         "id": "confirmations.redraft.message"
       },
       {
         "defaultMessage": "Block",
         "id": "confirmations.block.confirm"
       },
+      {
+        "defaultMessage": "Reply",
+        "id": "confirmations.reply.confirm"
+      },
+      {
+        "defaultMessage": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+        "id": "confirmations.reply.message"
+      },
       {
         "defaultMessage": "Are you sure you want to block {name}?",
         "id": "confirmations.block.message"
@@ -459,6 +483,15 @@
     ],
     "path": "app/javascript/mastodon/features/account_timeline/containers/header_container.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "No toots here!",
+        "id": "empty_column.account_timeline"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/account_timeline/index.json"
+  },
   {
     "descriptors": [
       {
@@ -557,6 +590,22 @@
         "defaultMessage": "Muted users",
         "id": "navigation_bar.mutes"
       },
+      {
+        "defaultMessage": "Feature on profile",
+        "id": "account.endorse"
+      },
+      {
+        "defaultMessage": "Don't feature on profile",
+        "id": "account.unendorse"
+      },
+      {
+        "defaultMessage": "Add or Remove from lists",
+        "id": "account.add_or_remove_from_list"
+      },
+      {
+        "defaultMessage": "Open moderation interface for @{name}",
+        "id": "status.admin_account"
+      },
       {
         "defaultMessage": "Information below may reflect the user's profile incompletely.",
         "id": "account.disclaimer_full"
@@ -602,6 +651,14 @@
         "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"
@@ -630,6 +687,10 @@
       {
         "defaultMessage": "Blocked users",
         "id": "column.blocks"
+      },
+      {
+        "defaultMessage": "You haven't blocked any users yet.",
+        "id": "empty_column.blocks"
       }
     ],
     "path": "app/javascript/mastodon/features/blocks/index.json"
@@ -844,6 +905,14 @@
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Dismiss suggestion",
+        "id": "suggestions.dismiss"
+      },
+      {
+        "defaultMessage": "You might be interested in…",
+        "id": "suggestions.header"
+      },
       {
         "defaultMessage": "People",
         "id": "search_results.accounts"
@@ -899,7 +968,7 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Add media",
+        "defaultMessage": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
         "id": "upload_button.label"
       }
     ],
@@ -1011,6 +1080,10 @@
       {
         "defaultMessage": "Logout",
         "id": "navigation_bar.logout"
+      },
+      {
+        "defaultMessage": "Compose new toot",
+        "id": "navigation_bar.compose"
       }
     ],
     "path": "app/javascript/mastodon/features/compose/index.json"
@@ -1037,6 +1110,10 @@
       {
         "defaultMessage": "Unhide {domain}",
         "id": "account.unblock_domain"
+      },
+      {
+        "defaultMessage": "There are no hidden domains yet.",
+        "id": "empty_column.domain_blocks"
       }
     ],
     "path": "app/javascript/mastodon/features/domain_blocks/index.json"
@@ -1046,10 +1123,23 @@
       {
         "defaultMessage": "Favourites",
         "id": "column.favourites"
+      },
+      {
+        "defaultMessage": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
+        "id": "empty_column.favourited_statuses"
       }
     ],
     "path": "app/javascript/mastodon/features/favourited_statuses/index.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "No one has favourited this toot yet. When someone does, they will show up here.",
+        "id": "empty_column.favourites"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/favourites/index.json"
+  },
   {
     "descriptors": [
       {
@@ -1068,10 +1158,32 @@
       {
         "defaultMessage": "Follow requests",
         "id": "column.follow_requests"
+      },
+      {
+        "defaultMessage": "You don't have any follow requests yet. When you receive one, it will show up here.",
+        "id": "empty_column.follow_requests"
       }
     ],
     "path": "app/javascript/mastodon/features/follow_requests/index.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "No one follows this user yet.",
+        "id": "account.followers.empty"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/followers/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "This user doesn't follow anyone yet.",
+        "id": "account.follows.empty"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/following/index.json"
+  },
   {
     "descriptors": [
       {
@@ -1147,8 +1259,8 @@
         "id": "getting_started.heading"
       },
       {
-        "defaultMessage": "Find friends from Twitter",
-        "id": "getting_started.find_friends"
+        "defaultMessage": "Profile directory",
+        "id": "getting_started.directory"
       },
       {
         "defaultMessage": "Invite people",
@@ -1166,6 +1278,10 @@
         "defaultMessage": "About this instance",
         "id": "navigation_bar.info"
       },
+      {
+        "defaultMessage": "Mobile apps",
+        "id": "navigation_bar.apps"
+      },
       {
         "defaultMessage": "Terms of service",
         "id": "getting_started.terms"
@@ -1191,6 +1307,39 @@
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Any of these",
+        "id": "hashtag.column_settings.tag_mode.any"
+      },
+      {
+        "defaultMessage": "All of these",
+        "id": "hashtag.column_settings.tag_mode.all"
+      },
+      {
+        "defaultMessage": "None of these",
+        "id": "hashtag.column_settings.tag_mode.none"
+      },
+      {
+        "defaultMessage": "Include additional tags in this column",
+        "id": "hashtag.column_settings.tag_toggle"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/hashtag_timeline/components/column_settings.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "or {additional}",
+        "id": "hashtag.column_header.tag_mode.any"
+      },
+      {
+        "defaultMessage": "and {additional}",
+        "id": "hashtag.column_header.tag_mode.all"
+      },
+      {
+        "defaultMessage": "without {additional}",
+        "id": "hashtag.column_header.tag_mode.none"
+      },
       {
         "defaultMessage": "There is nothing in this hashtag yet.",
         "id": "empty_column.hashtag"
@@ -1232,6 +1381,79 @@
     ],
     "path": "app/javascript/mastodon/features/home_timeline/index.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "First steps",
+        "id": "introduction.welcome.headline"
+      },
+      {
+        "defaultMessage": "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.",
+        "id": "introduction.welcome.text"
+      },
+      {
+        "defaultMessage": "Let's go!",
+        "id": "introduction.welcome.action"
+      },
+      {
+        "defaultMessage": "Home",
+        "id": "introduction.federation.home.headline"
+      },
+      {
+        "defaultMessage": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+        "id": "introduction.federation.home.text"
+      },
+      {
+        "defaultMessage": "Local",
+        "id": "introduction.federation.local.headline"
+      },
+      {
+        "defaultMessage": "Public posts from people on the same server as you will appear in the local timeline.",
+        "id": "introduction.federation.local.text"
+      },
+      {
+        "defaultMessage": "Federated",
+        "id": "introduction.federation.federated.headline"
+      },
+      {
+        "defaultMessage": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+        "id": "introduction.federation.federated.text"
+      },
+      {
+        "defaultMessage": "Next",
+        "id": "introduction.federation.action"
+      },
+      {
+        "defaultMessage": "Reply",
+        "id": "introduction.interactions.reply.headline"
+      },
+      {
+        "defaultMessage": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
+        "id": "introduction.interactions.reply.text"
+      },
+      {
+        "defaultMessage": "Boost",
+        "id": "introduction.interactions.reblog.headline"
+      },
+      {
+        "defaultMessage": "You can share other people's toots with your followers by boosting them.",
+        "id": "introduction.interactions.reblog.text"
+      },
+      {
+        "defaultMessage": "Favourite",
+        "id": "introduction.interactions.favourite.headline"
+      },
+      {
+        "defaultMessage": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+        "id": "introduction.interactions.favourite.text"
+      },
+      {
+        "defaultMessage": "Finish tutorial!",
+        "id": "introduction.interactions.action"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/introduction/index.json"
+  },
   {
     "descriptors": [
       {
@@ -1254,6 +1476,10 @@
         "defaultMessage": "to mention author",
         "id": "keyboard_shortcuts.mention"
       },
+      {
+        "defaultMessage": "to open author's profile",
+        "id": "keyboard_shortcuts.profile"
+      },
       {
         "defaultMessage": "to favourite",
         "id": "keyboard_shortcuts.favourite"
@@ -1302,6 +1528,54 @@
         "defaultMessage": "to un-focus compose textarea/search",
         "id": "keyboard_shortcuts.unfocus"
       },
+      {
+        "defaultMessage": "to open home timeline",
+        "id": "keyboard_shortcuts.home"
+      },
+      {
+        "defaultMessage": "to open notifications column",
+        "id": "keyboard_shortcuts.notifications"
+      },
+      {
+        "defaultMessage": "to open local timeline",
+        "id": "keyboard_shortcuts.local"
+      },
+      {
+        "defaultMessage": "to open federated timeline",
+        "id": "keyboard_shortcuts.federated"
+      },
+      {
+        "defaultMessage": "to open direct messages column",
+        "id": "keyboard_shortcuts.direct"
+      },
+      {
+        "defaultMessage": "to open \"get started\" column",
+        "id": "keyboard_shortcuts.start"
+      },
+      {
+        "defaultMessage": "to open favourites list",
+        "id": "keyboard_shortcuts.favourites"
+      },
+      {
+        "defaultMessage": "to open pinned toots list",
+        "id": "keyboard_shortcuts.pinned"
+      },
+      {
+        "defaultMessage": "to open your profile",
+        "id": "keyboard_shortcuts.my_profile"
+      },
+      {
+        "defaultMessage": "to open blocked users list",
+        "id": "keyboard_shortcuts.blocked"
+      },
+      {
+        "defaultMessage": "to open muted users list",
+        "id": "keyboard_shortcuts.muted"
+      },
+      {
+        "defaultMessage": "to open follow requests list",
+        "id": "keyboard_shortcuts.requests"
+      },
       {
         "defaultMessage": "to display this legend",
         "id": "keyboard_shortcuts.legend"
@@ -1309,6 +1583,19 @@
     ],
     "path": "app/javascript/mastodon/features/keyboard_shortcuts/index.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Remove from list",
+        "id": "lists.account.remove"
+      },
+      {
+        "defaultMessage": "Add to list",
+        "id": "lists.account.add"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/list_adder/components/list.json"
+  },
   {
     "descriptors": [
       {
@@ -1378,6 +1665,10 @@
       {
         "defaultMessage": "Your lists",
         "id": "lists.subheading"
+      },
+      {
+        "defaultMessage": "You don't have any lists yet. When you create one, it will show up here.",
+        "id": "empty_column.lists"
       }
     ],
     "path": "app/javascript/mastodon/features/lists/index.json"
@@ -1387,6 +1678,10 @@
       {
         "defaultMessage": "Muted users",
         "id": "column.mutes"
+      },
+      {
+        "defaultMessage": "You haven't muted any users yet.",
+        "id": "empty_column.mutes"
       }
     ],
     "path": "app/javascript/mastodon/features/mutes/index.json"
@@ -1402,6 +1697,14 @@
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Show",
+        "id": "notifications.column_settings.filter_bar.show"
+      },
+      {
+        "defaultMessage": "Display all categories",
+        "id": "notifications.column_settings.filter_bar.advanced"
+      },
       {
         "defaultMessage": "Desktop notifications",
         "id": "notifications.column_settings.alert"
@@ -1419,8 +1722,8 @@
         "id": "notifications.column_settings.push"
       },
       {
-        "defaultMessage": "This device",
-        "id": "notifications.column_settings.push_meta"
+        "defaultMessage": "Quick filter bar",
+        "id": "notifications.column_settings.filter_bar.category"
       },
       {
         "defaultMessage": "New followers:",
@@ -1441,6 +1744,31 @@
     ],
     "path": "app/javascript/mastodon/features/notifications/components/column_settings.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Mentions",
+        "id": "notifications.filter.mentions"
+      },
+      {
+        "defaultMessage": "Favourites",
+        "id": "notifications.filter.favourites"
+      },
+      {
+        "defaultMessage": "Boosts",
+        "id": "notifications.filter.boosts"
+      },
+      {
+        "defaultMessage": "Follows",
+        "id": "notifications.filter.follows"
+      },
+      {
+        "defaultMessage": "All",
+        "id": "notifications.filter.all"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/notifications/components/filter_bar.json"
+  },
   {
     "descriptors": [
       {
@@ -1506,6 +1834,15 @@
     ],
     "path": "app/javascript/mastodon/features/public_timeline/index.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "No one has boosted this toot yet. When someone does, they will show up here.",
+        "id": "status.reblogs.empty"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/reblogs/index.json"
+  },
   {
     "descriptors": [
       {
@@ -1601,6 +1938,14 @@
       {
         "defaultMessage": "Embed",
         "id": "status.embed"
+      },
+      {
+        "defaultMessage": "Open moderation interface for @{name}",
+        "id": "status.admin_account"
+      },
+      {
+        "defaultMessage": "Open this status in the moderation interface",
+        "id": "status.admin_status"
       }
     ],
     "path": "app/javascript/mastodon/features/status/components/action_bar.json"
@@ -1620,7 +1965,44 @@
         "id": "confirmations.redraft.confirm"
       },
       {
-        "defaultMessage": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+        "defaultMessage": "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.",
+        "id": "confirmations.redraft.message"
+      },
+      {
+        "defaultMessage": "Block",
+        "id": "confirmations.block.confirm"
+      },
+      {
+        "defaultMessage": "Reply",
+        "id": "confirmations.reply.confirm"
+      },
+      {
+        "defaultMessage": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+        "id": "confirmations.reply.message"
+      },
+      {
+        "defaultMessage": "Are you sure you want to block {name}?",
+        "id": "confirmations.block.message"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/status/containers/detailed_status_container.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Delete",
+        "id": "confirmations.delete.confirm"
+      },
+      {
+        "defaultMessage": "Are you sure you want to delete this status?",
+        "id": "confirmations.delete.message"
+      },
+      {
+        "defaultMessage": "Delete & redraft",
+        "id": "confirmations.redraft.confirm"
+      },
+      {
+        "defaultMessage": "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.",
         "id": "confirmations.redraft.message"
       },
       {
@@ -1635,6 +2017,18 @@
         "defaultMessage": "Show less for all",
         "id": "status.show_less_all"
       },
+      {
+        "defaultMessage": "Detailed conversation view",
+        "id": "status.detailed_status"
+      },
+      {
+        "defaultMessage": "Reply",
+        "id": "confirmations.reply.confirm"
+      },
+      {
+        "defaultMessage": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+        "id": "confirmations.reply.message"
+      },
       {
         "defaultMessage": "Are you sure you want to block {name}?",
         "id": "confirmations.block.message"
@@ -1689,6 +2083,15 @@
     ],
     "path": "app/javascript/mastodon/features/ui/components/bundle_modal_error.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Toot",
+        "id": "compose_form.publish"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/ui/components/columns_area.json"
+  },
   {
     "descriptors": [
       {
@@ -1753,111 +2156,6 @@
     ],
     "path": "app/javascript/mastodon/features/ui/components/mute_modal.json"
   },
-  {
-    "descriptors": [
-      {
-        "defaultMessage": "Home",
-        "id": "column.home"
-      },
-      {
-        "defaultMessage": "Notifications",
-        "id": "column.notifications"
-      },
-      {
-        "defaultMessage": "Local timeline",
-        "id": "column.community"
-      },
-      {
-        "defaultMessage": "Federated timeline",
-        "id": "column.public"
-      },
-      {
-        "defaultMessage": "Welcome to Mastodon!",
-        "id": "onboarding.page_one.welcome"
-      },
-      {
-        "defaultMessage": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-        "id": "onboarding.page_one.federation"
-      },
-      {
-        "defaultMessage": "Your full handle",
-        "id": "onboarding.page_one.full_handle"
-      },
-      {
-        "defaultMessage": "This is what you would tell your friends to search for.",
-        "id": "onboarding.page_one.handle_hint"
-      },
-      {
-        "defaultMessage": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-        "id": "onboarding.page_two.compose"
-      },
-      {
-        "defaultMessage": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-        "id": "onboarding.page_three.search"
-      },
-      {
-        "defaultMessage": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-        "id": "onboarding.page_three.profile"
-      },
-      {
-        "defaultMessage": "The home timeline shows posts from people you follow.",
-        "id": "onboarding.page_four.home"
-      },
-      {
-        "defaultMessage": "The notifications column shows when someone interacts with you.",
-        "id": "onboarding.page_four.notifications"
-      },
-      {
-        "defaultMessage": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-        "id": "onboarding.page_five.public_timelines"
-      },
-      {
-        "defaultMessage": "Your instance's admin is {admin}.",
-        "id": "onboarding.page_six.admin"
-      },
-      {
-        "defaultMessage": "Please read {domain}'s {guidelines}!",
-        "id": "onboarding.page_six.read_guidelines"
-      },
-      {
-        "defaultMessage": "community guidelines",
-        "id": "onboarding.page_six.guidelines"
-      },
-      {
-        "defaultMessage": "Almost done...",
-        "id": "onboarding.page_six.almost_done"
-      },
-      {
-        "defaultMessage": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-        "id": "onboarding.page_six.github"
-      },
-      {
-        "defaultMessage": "There are {apps} available for iOS, Android and other platforms.",
-        "id": "onboarding.page_six.apps_available"
-      },
-      {
-        "defaultMessage": "mobile apps",
-        "id": "onboarding.page_six.various_app"
-      },
-      {
-        "defaultMessage": "Bon Appetoot!",
-        "id": "onboarding.page_six.appetoot"
-      },
-      {
-        "defaultMessage": "Next",
-        "id": "onboarding.next"
-      },
-      {
-        "defaultMessage": "Done",
-        "id": "onboarding.done"
-      },
-      {
-        "defaultMessage": "Skip",
-        "id": "onboarding.skip"
-      }
-    ],
-    "path": "app/javascript/mastodon/features/ui/components/onboarding_modal.json"
-  },
   {
     "descriptors": [
       {
@@ -1976,6 +2274,10 @@
         "defaultMessage": "Sensitive content",
         "id": "status.sensitive_warning"
       },
+      {
+        "defaultMessage": "Media hidden",
+        "id": "status.media_hidden"
+      },
       {
         "defaultMessage": "Click to view",
         "id": "status.sensitive_toggle"
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index 7e8fa8b1720b0a150c6c3d8ab9c72018a93fe083..7b4852271bc08ba649ee4cb995a59454bc66cb90 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -1,17 +1,23 @@
 {
+  "account.add_or_remove_from_list": "Προσθήκη ή αφαίρεση από λίστες",
   "account.badges.bot": "Μποτ",
   "account.block": "Απόκλεισε τον/την @{name}",
-  "account.block_domain": "Απόκρυψε τα πάντα από τον/την",
+  "account.block_domain": "Απόκρυψε τα πάντα από το {domain}",
   "account.blocked": "Αποκλεισμένος/η",
   "account.direct": "Προσωπικό μήνυμα προς @{name}",
   "account.disclaimer_full": "Οι παρακάτω πληροφορίες μπορει να μην αντανακλούν το προφίλ του χρήστη επαρκως.",
   "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} μεταφέρθηκε στο:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Δείξε τις προωθήσεις του/της @{name}",
   "account.unblock": "Ξεμπλόκαρε τον/την @{name}",
   "account.unblock_domain": "Αποκάλυψε το {domain}",
+  "account.unendorse": "Άνευ προβολής στο προφίλ",
   "account.unfollow": "Διακοπή παρακολούθησης",
   "account.unmute": "Διακοπή αποσιώπησης του/της @{name}",
   "account.unmute_notifications": "Διακοπή αποσιώπησης ειδοποιήσεων του/της @{name}",
@@ -65,13 +72,13 @@
   "compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
   "compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
   "compose_form.lock_disclaimer.lock": "κλειδωμένος",
-  "compose_form.placeholder": "Τι έχεις στο μυαλό σου;",
+  "compose_form.placeholder": "Τι σκέφτεσαι;",
   "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.unmarked": "Μη κρυμμένο κείμενο",
   "compose_form.spoiler_placeholder": "Γράψε την προειδοποίησή σου εδώ",
   "confirmation_modal.cancel": "Άκυρο",
   "confirmations.block.confirm": "Απόκλεισε",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "Αποσιώπηση",
   "confirmations.mute.message": "Σίγουρα θες να αποσιωπήσεις τον/την {name};",
   "confirmations.redraft.confirm": "Διαγραφή & ξαναγράψιμο",
-  "confirmations.redraft.message": "Σίγουρα θέλεις να σβήσεις αυτή την κατάσταση και να την γράψεις ξανά; Θα χάσεις όλες τις απαντήσεις, αναφορές και τα αγαπημένα προς αυτή.",
+  "confirmations.redraft.message": "Σίγουρα θέλεις να σβήσεις αυτή την κατάσταση και να την ξαναγράψεις; Οι αναφορές και τα αγαπημένα της θα χαθούν ενώ οι απαντήσεις προς αυτή θα μείνουν ορφανές.",
+  "confirmations.reply.confirm": "Απάντησε",
+  "confirmations.reply.message": "Απαντώντας τώρα θα αντικαταστήσεις το κείμενο που ήδη γράφεις. Σίγουρα θέλεις να συνεχίσεις;",
   "confirmations.unfollow.confirm": "Διακοπή παρακολούθησης",
   "confirmations.unfollow.message": "Σίγουρα θες να πάψεις να ακολουθείς τον/την {name};",
   "embed.instructions": "Ενσωματώστε αυτή την κατάσταση στην ιστοσελίδα σας αντιγράφοντας τον παρακάτω κώδικα.",
@@ -104,51 +113,96 @@
   "emoji_button.search_results": "Αποτελέσματα αναζήτησης",
   "emoji_button.symbols": "Σύμβολα",
   "emoji_button.travel": "Ταξίδια & Τοποθεσίες",
+  "empty_column.account_timeline": "Δεν έχει τουτ εδώ!",
+  "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": "Δεν υπάρχει τίποτα εδώ! Γράψε κάτι δημόσιο, ή ακολούθησε χειροκίνητα χρήστες από άλλα instances για να τη γεμίσεις",
   "follow_request.authorize": "Ενέκρινε",
   "follow_request.reject": "Απέρριψε",
-  "getting_started.developers": "Προγραμματιστές",
-  "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Βρες φίλους/ες από το Twitter",
+  "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.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",
   "home.column_settings.basic": "Βασικά",
   "home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων",
   "home.column_settings.show_replies": "Εμφάνιση απαντήσεων",
-  "keyboard_shortcuts.back": "για επιστροφή πίσω",
-  "keyboard_shortcuts.boost": "για προώθηση",
-  "keyboard_shortcuts.column": "για εστίαση μιας κατάστασης σε μια από τις στήλες",
-  "keyboard_shortcuts.compose": "για εστίαση στην περιοχή κειμένου συγγραφής",
-  "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.down": "για κίνηση προς τα κάτω στη λίστα",
-  "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "για σημείωση αγαπημένου",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "introduction.federation.action": "Επόμενο",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "Οι δημόσιες αναρτήσεις από άλλους κόμβους του fediverse θα εμφανίζονται στην ομοσπονδιακή ροή.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "Οι αναρτήσεις όσων ακολουθείς θα εμφανίζονται στην αρχική ροή. Μπορείς να ακολουθήσεις όποιον θέλεις σε οποιονδήποτε κόμβο!",
+  "introduction.federation.local.headline": "Local",
+  "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": "Καλώς ήρθες στο fediverse! Σε πολύ λίγο θα μπορείς να στέλνεις δημοσιεύσεις και να μιλάς με τους φίλους σου σε πολλούς, διαφορετικούς κόμβους. Ο κόμβος {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.mention": "για να αναφέρεις το συγγραφέα",
-  "keyboard_shortcuts.reply": "για απάντηση",
-  "keyboard_shortcuts.search": "για εστίαση αναζήτησης",
-  "keyboard_shortcuts.toggle_hidden": "για εμφάνιση/απόκρυψη κειμένου πίσω από την προειδοποίηση",
-  "keyboard_shortcuts.toot": "για δημιουργία ολοκαίνουριου τουτ",
-  "keyboard_shortcuts.unfocus": "για την απο-εστίαση του πεδίου σύνθεσης/αναζήτησης",
-  "keyboard_shortcuts.up": "να κινηθείς προς την κορυφή της λίστας",
-  "lightbox.close": "Κλείσε",
+  "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": "κίνηση προς την κορυφή της λίστας",
+  "lightbox.close": "Κλείσιμο",
   "lightbox.next": "Επόμενο",
   "lightbox.previous": "Προηγούμενο",
   "lists.account.add": "Πρόσθεσε στη λίστα",
   "lists.account.remove": "Βγάλε από τη λίστα",
-  "lists.delete": "Delete list",
+  "lists.delete": "Διαγραφή λίστας",
   "lists.edit": "Επεξεργασία λίστας",
   "lists.new.create": "Προσθήκη λίστας",
   "lists.new.title_placeholder": "Τίτλος νέας λίστα",
@@ -159,21 +213,23 @@
   "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.domain_blocks": "Κρυμμένοι τομείς",
   "navigation_bar.edit_profile": "Επεξεργασία προφίλ",
   "navigation_bar.favourites": "Αγαπημένα",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Αποσιωπημένες λέξεις",
   "navigation_bar.follow_requests": "Αιτήματα ακολούθησης",
-  "navigation_bar.info": "Extended information",
+  "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.public_timeline": "Ομοσπονδιακή ροή",
@@ -186,35 +242,21 @@
   "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.push": "Άμεσες ειδοποιήσεις",
-  "notifications.column_settings.push_meta": "Αυτή η συσκευή",
   "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.group": "{count} ειδοποιήσεις",
-  "onboarding.done": "Έγινε",
-  "onboarding.next": "Επόμενο",
-  "onboarding.page_five.public_timelines": "Η τοπική ροή δείχνει τις δημόσιες δημοσιεύσεις από όσους εδρεύουν στον κόμβο {domain}. Η ομοσπονδιακή ροή δείχνει τις δημόσιες δημοσιεύσεις εκείνων που οι χρήστες του {domain} ακολουθούν. Αυτές οι είναι Δημόσιες Ροές, ένας ωραίος τρόπος να ανακαλύψεις καινούριους ανθρώπους.",
-  "onboarding.page_four.home": "Η αρχική ροή δείχνει καταστάσεις από ανθρώπους που ακολουθείς.",
-  "onboarding.page_four.notifications": "Η στήλη ειδοποιήσεων δείχνει πότε κάποιος αλληλεπιδράει μαζί σου.",
-  "onboarding.page_one.federation": "Το Mastodon είναι ένα δίκτυο ανεξάρτητων εξυπηρετητών (servers) που συνεργάζονται δημιουργώντας ένα μεγαλύτερο κοινωνικό δίκτυο. Τους εξυπηρετητές αυτούς τους λέμε κόμβους.",
-  "onboarding.page_one.full_handle": "Το πλήρες αναγνωριστικό σου",
-  "onboarding.page_one.handle_hint": "Αυτό είναι που θα πεις στους φίλους & φίλες σου να ψάξουν.",
-  "onboarding.page_one.welcome": "Καλώς όρισες στο Mastodon!",
-  "onboarding.page_six.admin": "Ο διαχειριστής του κόμβου σου είναι ο/η {admin}.",
-  "onboarding.page_six.almost_done": "Σχεδόν έτοιμοι...",
-  "onboarding.page_six.appetoot": "Καλά τουτ!",
-  "onboarding.page_six.apps_available": "Υπάρχουν {apps} για iOS, Android και άλλες πλατφόρμες.",
-  "onboarding.page_six.github": "Το Mastodon είναι ελεύθερο λογισμικό. Μπορείς να αναφέρεις σφάλματα, να αιτηθείς νέες λειτουργίες ή να συνεισφέρεις κώδικα στο {github}.",
-  "onboarding.page_six.guidelines": "οδηγίες κοινότητας",
-  "onboarding.page_six.read_guidelines": "Παρακαλώ διάβασε τις {guidelines} του κόμβου {domain}!",
-  "onboarding.page_six.various_app": "εφαρμογές κινητών",
-  "onboarding.page_three.profile": "Επεξεργάσου το προφίλ σου για να αλλάξεις την εικόνα σου, το βιογραφικό σου και το εμφανιζόμενο όνομά σου. Εκεί θα βρεις επίσης κι άλλες προτιμήσεις.",
-  "onboarding.page_three.search": "Χρησιμοποίησε την μπάρα αναζήτησης για να βρεις ανθρώπους και να δεις ταμπέλες όπως για παράδειγμα {illustration} και {introductions}. Για να ψάξεις κάποιον ή κάποια που δεν είναι σε αυτόν τον κόμβο, χρησιμοποίησε το πλήρες αναγνωριστικό τους.",
-  "onboarding.page_two.compose": "Γράψε δημοσιεύσεις στην κολώνα συγγραφής. Μπορείς να ανεβάσεις εικόνες, να αλλάξεις τις ρυθμίσεις ιδιωτικότητας και να προσθέσεις προειδοποιήσεις περιεχομένου με τα παρακάτω εικονίδια.",
-  "onboarding.skip": "Παράληψη",
   "privacy.change": "Προσαρμογή ιδιωτικότητας δημοσίευσης",
   "privacy.direct.long": "Δημοσίευση μόνο σε όσους και όσες αναφέρονται",
   "privacy.direct.short": "Προσωπικά",
@@ -222,15 +264,15 @@
   "privacy.private.short": "Μόνο ακόλουθοι",
   "privacy.public.long": "Δημοσίευσε στις δημόσιες ροές",
   "privacy.public.short": "Δημόσιο",
-  "privacy.unlisted.long": "Do not show in public timelines",
+  "privacy.unlisted.long": "Μην δημοσιεύσεις στις δημόσιες ροές",
   "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": "Ο λογαριασμός είναι από διαφορετικό διακομιστή. Να σταλεί ανώνυμο αντίγραφο της καταγγελίας κι εκεί;",
@@ -242,18 +284,21 @@
   "search_popout.search_format": "Προχωρημένη αναζήτηση",
   "search_popout.tips.full_text": "Απλό κείμενο που επιστρέφει καταστάσεις που έχεις γράψει, σημειώσει ως αγαπημένες, προωθήσει ή έχεις αναφερθεί σε αυτές, καθώς και όσα ονόματα χρηστών και ταμπέλες ταιριάζουν.",
   "search_popout.tips.hashtag": "ταμπέλα",
-  "search_popout.tips.status": "status",
-  "search_popout.tips.text": "Απλό κείμενο που επιστρέφει ταιριαστά ονόματα και ταμπέλες",
+  "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}}",
+  "search_results.total": "{count, number} {count, plural, ένα {result} υπόλοιπα {results}}",
   "standalone.public_title": "Μια πρώτη γεύση...",
-  "status.block": "Block @{name}",
+  "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.delete": "Διαγραφή",
+  "status.detailed_status": "Προβολή λεπτομερειών συζήτησης",
   "status.direct": "Προσωπικό μήνυμα προς @{name}",
   "status.embed": "Ενσωμάτωσε",
   "status.favourite": "Σημείωσε ως αγαπημένο",
@@ -267,13 +312,15 @@
   "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.report": "Κατάγγειλε @{name}",
   "status.sensitive_toggle": "Κλικ για να δεις",
   "status.sensitive_warning": "Ευαίσθητο περιεχόμενο",
   "status.share": "Μοιράσου",
@@ -281,8 +328,11 @@
   "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": "Τοπικά",
@@ -291,9 +341,9 @@
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} μιλάνε",
   "ui.beforeunload": "Το προσχέδιό σου θα χαθεί αν φύγεις από το Mastodon.",
   "upload_area.title": "Drag & drop για να ανεβάσεις",
-  "upload_button.label": "Πρόσθεσε πολυμέσα",
+  "upload_button.label": "Πρόσθεσε πολυμέσα (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Περιέγραψε για όσους & όσες έχουν προβλήματα όρασης",
-  "upload_form.focus": "Περικοπή",
+  "upload_form.focus": "Αλλαγή προεπισκόπησης",
   "upload_form.undo": "Διαγραφή",
   "upload_progress.label": "Ανεβαίνει...",
   "video.close": "Κλείσε το βίντεο",
@@ -302,7 +352,7 @@
   "video.fullscreen": "Πλήρης οθόνη",
   "video.hide": "Κρύψε βίντεο",
   "video.mute": "Σίγαση ήχου",
-  "video.pause": "Pause",
+  "video.pause": "Παύση",
   "video.play": "Αναπαραγωγή",
   "video.unmute": "Αναπαραγωγή ήχου"
 }
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 887c668ed3add320c2494df5267deed03ea2320f..1dbf2802226aeb444519e3bef60d5cd63df8479e 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -1,4 +1,5 @@
 {
+  "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}",
@@ -7,11 +8,16 @@
   "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:",
@@ -26,6 +32,7 @@
   "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}",
@@ -85,7 +92,9 @@
   "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.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.",
@@ -104,41 +113,86 @@
   "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",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "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 for 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",
+  "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.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
@@ -159,8 +213,10 @@
   "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",
@@ -186,35 +242,21 @@
   "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.push_meta": "This device",
   "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",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
-  "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -250,10 +292,13 @@
   "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.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
@@ -267,9 +312,11 @@
   "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",
@@ -281,8 +328,11 @@
   "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",
@@ -291,9 +341,9 @@
   "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_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Describe for the visually impaired",
-  "upload_form.focus": "Crop",
+  "upload_form.focus": "Change preview",
   "upload_form.undo": "Delete",
   "upload_progress.label": "Uploading...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index be2bc3d65d08309a85a4e65a5b349c34996eaf22..8be964a52a7ab9cefee325d57350a0e0751a6b72 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Aldoni al aÅ­ forigi el listoj",
   "account.badges.bot": "Roboto",
   "account.block": "Bloki @{name}",
   "account.block_domain": "Kaŝi ĉion de {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Sekvi",
   "account.followers": "Sekvantoj",
+  "account.followers.empty": "AnkoraÅ­ neniu sekvas tiun uzanton.",
   "account.follows": "Sekvatoj",
+  "account.follows.empty": "Tiu uzanto ankoraÅ­ ne sekvas iun.",
   "account.follows_you": "Sekvas vin",
   "account.hide_reblogs": "Kaŝi diskonigojn de @{name}",
+  "account.link_verified_on": "La posedanto de tiu ligilo estis kontrolita je {date}",
+  "account.locked_info": "La privateco de tiu konto estas elektita kiel fermita. La posedanto povas mane akcepti tiun, kiu povas sekvi rin.",
   "account.media": "Aŭdovidaĵoj",
   "account.mention": "Mencii @{name}",
   "account.moved_to": "{name} moviĝis al:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Montri diskonigojn de @{name}",
   "account.unblock": "Malbloki @{name}",
   "account.unblock_domain": "Malkaŝi {domain}",
+  "account.unendorse": "Ne montri en profilo",
   "account.unfollow": "Ne plu sekvi",
   "account.unmute": "Malsilentigi @{name}",
   "account.unmute_notifications": "Malsilentigi sciigojn de @{name}",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "Silentigi",
   "confirmations.mute.message": "Ĉu vi certas, ke vi volas silentigi {name}?",
   "confirmations.redraft.confirm": "Forigi kaj reskribi",
-  "confirmations.redraft.message": "Ĉu vi certas, ke vi volas forigi tiun mesaĝon kaj reskribi ĝin? Vi perdos ĉiujn respondojn, diskonigojn kaj stelumojn ligitajn al ĝi.",
+  "confirmations.redraft.message": "Ĉu vi certas ke vi volas forigi tiun mesaĝon kaj reskribi ĝin? Ĉiuj diskonigoj kaj stelumoj estos perditaj, kaj respondoj al la originala mesaĝo estos senparentaj.",
+  "confirmations.reply.confirm": "Respondi",
+  "confirmations.reply.message": "Respondi nun anstataŭigos la mesaĝon, kiun vi nun skribas. Ĉu vi certas, ke vi volas daŭrigi?",
   "confirmations.unfollow.confirm": "Ne plu sekvi",
   "confirmations.unfollow.message": "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?",
   "embed.instructions": "Enkorpigu ĉi tiun mesaĝon en vian retejon per kopio de la suba kodo.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Serĉaj rezultoj",
   "emoji_button.symbols": "Simboloj",
   "emoji_button.travel": "Vojaĝoj kaj lokoj",
+  "empty_column.account_timeline": "Neniu mesaĝo ĉi tie!",
+  "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.",
+  "empty_column.domain_blocks": "AnkoraÅ­ neniu domajno estas blokita.",
+  "empty_column.favourited_statuses": "Vi ankoraŭ ne stelumis mesaĝon. Kiam vi stelumos iun, tiu aperos ĉi tie.",
+  "empty_column.favourites": "Ankoraŭ neniu stelumis tiun mesaĝon. Kiam iu faros tion, tiu aperos ĉi tie.",
+  "empty_column.follow_requests": "Vi ne ankoraŭ havas iun peton de sekvado. Kiam vi ricevos unu, ĝi aperos ĉi tie.",
   "empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.",
   "empty_column.home": "Via hejma tempolinio estas malplena! Vizitu {public} aŭ uzu la serĉilon por renkonti aliajn uzantojn.",
   "empty_column.home.public_timeline": "la publikan tempolinion",
   "empty_column.list": "Ankoraŭ estas nenio en ĉi tiu listo. Kiam membroj de ĉi tiu listo afiŝos novajn mesaĝojn, ili aperos ĉi tie.",
+  "empty_column.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",
   "follow_request.authorize": "Rajtigi",
   "follow_request.reject": "Rifuzi",
   "getting_started.developers": "Programistoj",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Dokumentado",
-  "getting_started.find_friends": "Trovi amikojn el Twitter",
   "getting_started.heading": "Por komenci",
   "getting_started.invite": "Inviti homojn",
   "getting_started.open_source_notice": "Mastodon estas malfermitkoda programo. Vi povas kontribui aÅ­ raporti problemojn en GitHub je {github}.",
   "getting_started.security": "Sekureco",
   "getting_started.terms": "Uzkondiĉoj",
+  "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.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",
   "home.column_settings.basic": "Bazaj agordoj",
   "home.column_settings.show_reblogs": "Montri diskonigojn",
   "home.column_settings.show_replies": "Montri respondojn",
+  "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.",
   "keyboard_shortcuts.back": "por reveni",
+  "keyboard_shortcuts.blocked": "por malfermi la liston de blokitaj uzantoj",
   "keyboard_shortcuts.boost": "por diskonigi",
   "keyboard_shortcuts.column": "por fokusigi mesaĝon en unu el la kolumnoj",
   "keyboard_shortcuts.compose": "por fokusigi la tekstujon",
   "keyboard_shortcuts.description": "Priskribo",
+  "keyboard_shortcuts.direct": "por malfermi la kolumnon de rektaj mesaĝoj",
   "keyboard_shortcuts.down": "por iri suben en la listo",
   "keyboard_shortcuts.enter": "por malfermi mesaĝon",
   "keyboard_shortcuts.favourite": "por stelumi",
+  "keyboard_shortcuts.favourites": "por malfermi la liston de stelumoj",
+  "keyboard_shortcuts.federated": "por malfermi la frataran tempolinion",
   "keyboard_shortcuts.heading": "Klavaraj mallongigoj",
+  "keyboard_shortcuts.home": "por malfermi la hejman tempolinion",
   "keyboard_shortcuts.hotkey": "Rapidklavo",
   "keyboard_shortcuts.legend": "por montri ĉi tiun noton",
+  "keyboard_shortcuts.local": "por malfermi la lokan tempolinion",
   "keyboard_shortcuts.mention": "por mencii la aÅ­toron",
+  "keyboard_shortcuts.muted": "por malfermi la liston de silentigitaj uzantoj",
+  "keyboard_shortcuts.my_profile": "por malfermi vian profilon",
+  "keyboard_shortcuts.notifications": "por malfermi la kolumnon de sciigoj",
+  "keyboard_shortcuts.pinned": "por malfermi la liston de alpinglitaj mesaĝoj",
+  "keyboard_shortcuts.profile": "por malfermi la profilon de la aÅ­toro",
   "keyboard_shortcuts.reply": "por respondi",
+  "keyboard_shortcuts.requests": "por malfermi la liston de petoj de sekvado",
   "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.toot": "por komenci tute novan mesaĝon",
   "keyboard_shortcuts.unfocus": "por malfokusigi la tekstujon aŭ la serĉilon",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Ne trovita",
   "missing_indicator.sublabel": "Ĉi tiu elemento ne estis trovita",
   "mute_modal.hide_notifications": "Ĉu vi volas kaŝi la sciigojn el ĉi tiu uzanto?",
+  "navigation_bar.apps": "Telefonaj aplikaĵoj",
   "navigation_bar.blocks": "Blokitaj uzantoj",
   "navigation_bar.community_timeline": "Loka tempolinio",
+  "navigation_bar.compose": "Skribi novan mesaĝon",
   "navigation_bar.direct": "Rektaj mesaĝoj",
   "navigation_bar.discover": "Esplori",
   "navigation_bar.domain_blocks": "Kaŝitaj domajnoj",
   "navigation_bar.edit_profile": "Redakti profilon",
   "navigation_bar.favourites": "Stelumoj",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Silentigitaj vortoj",
   "navigation_bar.follow_requests": "Petoj de sekvado",
   "navigation_bar.info": "Pri ĉi tiu nodo",
   "navigation_bar.keyboard_shortcuts": "Rapidklavoj",
@@ -186,35 +242,21 @@
   "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.follow": "Novaj sekvantoj:",
   "notifications.column_settings.mention": "Mencioj:",
   "notifications.column_settings.push": "Puŝsciigoj",
-  "notifications.column_settings.push_meta": "Ĉi tiu aparato",
   "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.group": "{count} sciigoj",
-  "onboarding.done": "Farita",
-  "onboarding.next": "Sekva",
-  "onboarding.page_five.public_timelines": "La loka tempolinio montras publikajn mesaĝojn de ĉiuj en {domain}. La fratara tempolinio montras publikajn mesaĝojn de ĉiuj, kiuj estas sekvataj de homoj en {domain}. Tio estas la publikaj tempolinioj, kio estas bona maniero por malkovri novajn homojn.",
-  "onboarding.page_four.home": "La hejma tempolinio montras mesaĝojn de ĉiuj uzantoj, kiujn vi sekvas.",
-  "onboarding.page_four.notifications": "La sciiga kolumno montras kiam iu interagas kun vi.",
-  "onboarding.page_one.federation": "Mastodon estas reto de sendependaj serviloj, unuiĝintaj por krei pligrandan socian reton. Ni nomas tiujn servilojn nodoj.",
-  "onboarding.page_one.full_handle": "Via kompleta uzantnomo",
-  "onboarding.page_one.handle_hint": "Jen kion vi petus al viaj amikoj serĉi.",
-  "onboarding.page_one.welcome": "Bonvenon en Mastodon!",
-  "onboarding.page_six.admin": "Via noda administranto estas {admin}.",
-  "onboarding.page_six.almost_done": "Preskaŭ finita…",
-  "onboarding.page_six.appetoot": "Saĝan mesaĝadon!",
-  "onboarding.page_six.apps_available": "{apps} estas disponeblaj por iOS, Android kaj aliaj platformoj.",
-  "onboarding.page_six.github": "Mastodon estas libera, senpaga kaj malfermitkoda programo. Vi povas raporti cimojn, proponi funkciojn aÅ­ kontribui al la kodo en {github}.",
-  "onboarding.page_six.guidelines": "komunumaj gvidlinioj",
-  "onboarding.page_six.read_guidelines": "Bonvolu atenti pri la {guidelines} de {domain}!",
-  "onboarding.page_six.various_app": "telefonaj aplikaĵoj",
-  "onboarding.page_three.profile": "Redaktu vian profilon por ŝanĝi vian profilbildon, priskribon kaj nomon. Vi ankaŭ trovos tie aliajn agordojn.",
-  "onboarding.page_three.search": "Uzu la serĉilon por trovi uzantojn kaj esplori kradvortojn, tiel {illustration} kaj {introductions}. Por trovi iun, kiu ne estas en ĉi tiu nodo, uzu ties kompletan uzantnomon.",
-  "onboarding.page_two.compose": "Skribu mesaĝojn en la skriba kolumno. Vi povas alŝuti bildojn, ŝanĝi privatecajn agordojn, kaj aldoni avertojn pri la enhavo per la subaj bildetoj.",
-  "onboarding.skip": "Preterpasi",
   "privacy.change": "Agordi mesaĝan privatecon",
   "privacy.direct.long": "Afiŝi nur al menciitaj uzantoj",
   "privacy.direct.short": "Rekta",
@@ -250,14 +292,17 @@
   "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.block": "Bloki @{name}",
   "status.cancel_reblog_private": "Eksdiskonigi",
   "status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",
   "status.delete": "Forigi",
+  "status.detailed_status": "Detala konversacia vido",
   "status.direct": "Rekte mesaĝi @{name}",
   "status.embed": "Enkorpigi",
   "status.favourite": "Stelumi",
-  "status.filtered": "Filtered",
+  "status.filtered": "Filtrita",
   "status.load_more": "Åœargi pli",
   "status.media_hidden": "Aŭdovidaĵo kaŝita",
   "status.mention": "Mencii @{name}",
@@ -267,9 +312,11 @@
   "status.open": "Grandigi",
   "status.pin": "Alpingli profile",
   "status.pinned": "Alpinglita mesaĝo",
+  "status.read_more": "Legi pli",
   "status.reblog": "Diskonigi",
   "status.reblog_private": "Diskonigi al la originala atentaro",
   "status.reblogged_by": "{name} diskonigis",
+  "status.reblogs.empty": "Ankoraŭ neniu diskonigis tiun mesaĝon. Kiam iu faros tion, tiu aperos ĉi tie.",
   "status.redraft": "Forigi kaj reskribi",
   "status.reply": "Respondi",
   "status.replyAll": "Respondi al la fadeno",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Malgrandigi ĉiujn",
   "status.show_more": "Grandigi",
   "status.show_more_all": "Grandigi ĉiujn",
-  "status.unmute_conversation": "Malsilentigi konversacion",
+  "status.show_thread": "Montri la fadenon",
+  "status.unmute_conversation": "Malsilentigi la konversacion",
   "status.unpin": "Depingli de profilo",
+  "suggestions.dismiss": "Forigi la proponon",
+  "suggestions.header": "Vi povus interesiĝi pri…",
   "tabs_bar.federated_timeline": "Fratara tempolinio",
   "tabs_bar.home": "Hejmo",
   "tabs_bar.local_timeline": "Loka tempolinio",
@@ -291,7 +341,7 @@
   "trends.count_by_accounts": "{count} {rawCount, pluraj, unu {person} alia(j) {people}} 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",
+  "upload_button.label": "Aldoni aŭdovidaĵon (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Priskribi por misvidantaj homoj",
   "upload_form.focus": "Stuci",
   "upload_form.undo": "Forigi",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index d4db8d15fb9e3668032706bfa245c5d932e61468..4f73dbba244fc17d9cfbf663f92d5ce866b82cd8 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Bloquear",
   "account.block_domain": "Ocultar todo de {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
+  "account.followers.empty": "Nadie sigue a este usuario todavía.",
   "account.follows": "Sigue",
+  "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.mention": "Mencionar a @{name}",
   "account.moved_to": "{name} se ha mudado a:",
@@ -26,11 +32,12 @@
   "account.show_reblogs": "Mostrar retoots de @{name}",
   "account.unblock": "Desbloquear a @{name}",
   "account.unblock_domain": "Mostrar a {domain}",
+  "account.unendorse": "No mostrar en el perfil",
   "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": "An unexpected error occurred.",
+  "alert.unexpected.message": "Hubo un error inesperado.",
   "alert.unexpected.title": "Oops!",
   "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.",
@@ -41,8 +48,8 @@
   "bundle_modal_error.retry": "Inténtalo de nuevo",
   "column.blocks": "Usuarios bloqueados",
   "column.community": "Línea de tiempo local",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
+  "column.direct": "Mensajes directos",
+  "column.domain_blocks": "Dominios ocultos",
   "column.favourites": "Favoritos",
   "column.follow_requests": "Solicitudes de seguimiento",
   "column.home": "Inicio",
@@ -59,9 +66,9 @@
   "column_header.show_settings": "Mostrar ajustes",
   "column_header.unpin": "Dejar de fijar",
   "column_subheading.settings": "Ajustes",
-  "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": "Solo media",
+  "compose_form.direct_message_warning": "Este toot solo será enviado a los usuarios mencionados.",
+  "compose_form.direct_message_warning_learn_more": "Aprender mas",
   "compose_form.hashtag_warning": "Este toot no se mostrará bajo hashtags porque no es público. Sólo los toots públicos se pueden buscar por hashtag.",
   "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",
@@ -81,11 +88,13 @@
   "confirmations.delete_list.confirm": "Delete",
   "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 entero? En algunos casos es preferible bloquear o silenciar objetivos determinados.",
+  "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.",
   "confirmations.mute.confirm": "Silenciar",
   "confirmations.mute.message": "¿Estás seguro de que quieres silenciar a {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.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.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}?",
   "embed.instructions": "Añade este toot a tu sitio web con el siguiente código.",
@@ -104,42 +113,87 @@
   "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.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": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.direct": "Aún no tienes ningún mensaje directo. Cuando envíes o recibas uno, se mostrará aquí.",
+  "empty_column.domain_blocks": "Todavía no hay dominios ocultos.",
+  "empty_column.favourited_statuses": "Aún no tienes toots preferidos. Cuando marques uno como favorito, aparecerá aquí.",
+  "empty_column.favourites": "Nadie ha marcado este toot como preferido. Cuando alguien lo haga, aparecerá aquí.",
+  "empty_column.follow_requests": "No tienes ninguna petición de seguidor. Cuando recibas una, se mostrará aquí.",
   "empty_column.hashtag": "No hay nada en este hashtag aún.",
   "empty_column.home": "No estás siguiendo a nadie aún. Visita {public} o haz búsquedas para empezar y conocer gente nueva.",
   "empty_column.home.public_timeline": "la línea de tiempo pública",
   "empty_column.list": "No hay nada en esta lista aún. Cuando miembros de esta lista publiquen nuevos estatus, estos aparecerán qui.",
+  "empty_column.lists": "No tienes ninguna lista. cuando crees una, se mostrará aquí.",
+  "empty_column.mutes": "Aún no has silenciado a ningún usuario.",
   "empty_column.notifications": "No tienes ninguna notificación aún. Interactúa con otros para empezar una conversación.",
   "empty_column.public": "¡No hay nada aquí! Escribe algo públicamente, o sigue usuarios de otras instancias manualmente para llenarlo",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rechazar",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Desarrolladores",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Primeros pasos",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Invitar usuarios",
   "getting_started.open_source_notice": "Mastodon es software libre. Puedes contribuir o reportar errores en {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
+  "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_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": "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",
+  "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": "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.direct": "abrir la columna de mensajes directos",
   "keyboard_shortcuts.down": "mover hacia abajo en la lista",
   "keyboard_shortcuts.enter": "to open status",
   "keyboard_shortcuts.favourite": "añadir a favoritos",
+  "keyboard_shortcuts.favourites": "abrir la lista de favoritos",
+  "keyboard_shortcuts.federated": "abrir el timeline federado",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "keyboard_shortcuts.home": "abrir el timeline propio",
   "keyboard_shortcuts.hotkey": "Tecla caliente",
   "keyboard_shortcuts.legend": "para mostrar esta leyenda",
+  "keyboard_shortcuts.local": "abrir el timeline local",
   "keyboard_shortcuts.mention": "para mencionar al autor",
+  "keyboard_shortcuts.muted": "abrir la lista de usuarios silenciados",
+  "keyboard_shortcuts.my_profile": "abrir tu perfil",
+  "keyboard_shortcuts.notifications": "abrir la columna de notificaciones",
+  "keyboard_shortcuts.pinned": "abrir la lista de toots destacados",
+  "keyboard_shortcuts.profile": "abrir el perfil del autor",
   "keyboard_shortcuts.reply": "para responder",
+  "keyboard_shortcuts.requests": "abrir la lista de peticiones de seguidores",
   "keyboard_shortcuts.search": "para poner el foco en la búsqueda",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.start": "abrir la columna \"comenzar\"",
+  "keyboard_shortcuts.toggle_hidden": "mostrar/ocultar texto tras aviso de contenido (CW)",
   "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",
@@ -159,17 +213,19 @@
   "missing_indicator.label": "No encontrado",
   "missing_indicator.sublabel": "No se encontró este recurso",
   "mute_modal.hide_notifications": "Ocultar notificaciones de este usuario?",
+  "navigation_bar.apps": "Aplicaciones móviles",
   "navigation_bar.blocks": "Usuarios bloqueados",
   "navigation_bar.community_timeline": "Historia local",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.compose": "Escribir un nuevo toot",
+  "navigation_bar.direct": "Mensajes directos",
+  "navigation_bar.discover": "Descubrir",
+  "navigation_bar.domain_blocks": "Dominios ocultos",
   "navigation_bar.edit_profile": "Editar perfil",
   "navigation_bar.favourites": "Favoritos",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Palabras silenciadas",
   "navigation_bar.follow_requests": "Solicitudes para seguirte",
   "navigation_bar.info": "Información adicional",
-  "navigation_bar.keyboard_shortcuts": "Atajos de teclado",
+  "navigation_bar.keyboard_shortcuts": "Atajos",
   "navigation_bar.lists": "Listas",
   "navigation_bar.logout": "Cerrar sesión",
   "navigation_bar.mutes": "Usuarios silenciados",
@@ -177,7 +233,7 @@
   "navigation_bar.pins": "Toots fijados",
   "navigation_bar.preferences": "Preferencias",
   "navigation_bar.public_timeline": "Historia federada",
-  "navigation_bar.security": "Security",
+  "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",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "¿Seguro que quieres limpiar permanentemente todas tus notificaciones?",
   "notifications.column_settings.alert": "Notificaciones de escritorio",
   "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.follow": "Nuevos seguidores:",
   "notifications.column_settings.mention": "Menciones:",
   "notifications.column_settings.push": "Notificaciones push",
-  "notifications.column_settings.push_meta": "Este dispositivo",
   "notifications.column_settings.reblog": "Retoots:",
   "notifications.column_settings.show": "Mostrar en columna",
   "notifications.column_settings.sound": "Reproducir sonido",
-  "notifications.group": "{count} notifications",
-  "onboarding.done": "Listo",
-  "onboarding.next": "Siguiente",
-  "onboarding.page_five.public_timelines": "La línea de tiempo local muestra toots públicos de todos en {domain}. La línea de tiempo federada muestra toots públicos de cualquiera a quien la gente de {domain} siga. Estas son las líneas de tiempo públicas, una buena forma de conocer gente nueva.",
-  "onboarding.page_four.home": "La línea de tiempo principal muestra toots de gente que sigues.",
-  "onboarding.page_four.notifications": "Las notificaciones se muestran cuando alguien interactúa contigo.",
-  "onboarding.page_one.federation": "Mastodon es una red de servidores federados que conforman una red social aún más grande. Llamamos a estos servidores instancias.",
-  "onboarding.page_one.full_handle": "Tu sobrenombre completo",
-  "onboarding.page_one.handle_hint": "Esto es lo que dirías a tus amistades que buscaran.",
-  "onboarding.page_one.welcome": "¡Bienvenido a Mastodon!",
-  "onboarding.page_six.admin": "El administrador de tu instancia es {admin}.",
-  "onboarding.page_six.almost_done": "Ya casi…",
-  "onboarding.page_six.appetoot": "¡Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Hay {apps} disponibles para iOS, Android y otras plataformas.",
-  "onboarding.page_six.github": "Mastodon es software libre. Puedes reportar errores, pedir funciones nuevas, o contribuir al código en {github}.",
-  "onboarding.page_six.guidelines": "guías de la comunidad",
-  "onboarding.page_six.read_guidelines": "¡Por favor lee las {guidelines} de {domain}!",
-  "onboarding.page_six.various_app": "aplicaciones móviles",
-  "onboarding.page_three.profile": "Edita tu perfil para cambiar tu avatar, biografía y nombre de cabecera. Ahí, también encontrarás otros ajustes.",
-  "onboarding.page_three.search": "Usa la barra de búsqueda y revisa hashtags, como {illustration} y {introductions}. Para ver a alguien que no es de tu propia instancia, usa su nombre de usuario completo.",
-  "onboarding.page_two.compose": "Escribe toots en la columna de redacción. Puedes subir imágenes, cambiar ajustes de privacidad, y añadir advertencias de contenido con los siguientes íconos.",
-  "onboarding.skip": "Saltar",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.group": "{count} notificaciones",
   "privacy.change": "Ajustar privacidad",
   "privacy.direct.long": "Sólo mostrar a los usuarios mencionados",
   "privacy.direct.short": "Directo",
@@ -246,18 +288,21 @@
   "search_popout.tips.text": "El texto simple devuelve correspondencias de nombre, usuario y hashtag",
   "search_popout.tips.user": "usuario",
   "search_results.accounts": "Gente",
-  "search_results.hashtags": "Hashtags",
+  "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": "Unboost",
+  "status.cancel_reblog_private": "Des-impulsar",
   "status.cannot_reblog": "Este toot no puede retootearse",
   "status.delete": "Borrar",
-  "status.direct": "Direct message @{name}",
+  "status.detailed_status": "Vista de conversación detallada",
+  "status.direct": "Mensaje directo a @{name}",
   "status.embed": "Incrustado",
   "status.favourite": "Favorito",
-  "status.filtered": "Filtered",
+  "status.filtered": "Filtrado",
   "status.load_more": "Cargar más",
   "status.media_hidden": "Contenido multimedia oculto",
   "status.mention": "Mencionar",
@@ -267,10 +312,12 @@
   "status.open": "Expandir estado",
   "status.pin": "Fijar",
   "status.pinned": "Toot fijado",
+  "status.read_more": "Read more",
   "status.reblog": "Retootear",
-  "status.reblog_private": "Boost to original audience",
+  "status.reblog_private": "Implusar a la audiencia original",
   "status.reblogged_by": "Retooteado por {name}",
-  "status.redraft": "Delete & re-draft",
+  "status.reblogs.empty": "Nadie impulsó este toot todavía. Cuando alguien lo haga, aparecerá aqui.",
+  "status.redraft": "Borrar y volver a borrador",
   "status.reply": "Responder",
   "status.replyAll": "Responder al hilo",
   "status.report": "Reportar",
@@ -281,20 +328,23 @@
   "status.show_less_all": "Mostrar menos para todo",
   "status.show_more": "Mostrar más",
   "status.show_more_all": "Mostrar más para todo",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Dejar de silenciar conversación",
   "status.unpin": "Dejar de fijar",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Federado",
   "tabs_bar.home": "Inicio",
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificaciones",
-  "tabs_bar.search": "Search",
+  "tabs_bar.search": "Buscar",
   "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",
+  "upload_button.label": "Subir multimedia (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Describir para los usuarios con dificultad visual",
   "upload_form.focus": "Recortar",
-  "upload_form.undo": "Deshacer",
+  "upload_form.undo": "Borrar",
   "upload_progress.label": "Subiendo…",
   "video.close": "Cerrar video",
   "video.exit_fullscreen": "Salir de pantalla completa",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index 33f477af38f6797547b4c8b30b9ce941dd419062..0602fbf9e97bf590cb2508f29a3d0ede02f1f00f 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Gehitu edo kendu zerrendetatik",
   "account.badges.bot": "Bot",
   "account.block": "Blokeatu @{name}",
   "account.block_domain": "Ezkutatu {domain} domeinuko guztia",
@@ -6,19 +7,24 @@
   "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": "Profila aldatu",
+  "account.edit_profile": "Aldatu profila",
+  "account.endorse": "Nabarmendu profilean",
   "account.follow": "Jarraitu",
   "account.followers": "Jarraitzaileak",
+  "account.followers.empty": "Ez du inork erabiltzaile hau jarraitzen oraindik.",
   "account.follows": "Jarraitzen",
-  "account.follows_you": "Jarraitzen zaitu",
+  "account.follows.empty": "Erabiltzaile honek ez du inor jarraitzen oraindik.",
+  "account.follows_you": "Jarraitzen dizu",
   "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.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": "Toot-ak",
+  "account.posts": "Tootak",
   "account.posts_with_replies": "Toot eta erantzunak",
   "account.report": "Salatu @{name}",
   "account.requested": "Onarpenaren zain. Klikatu jarraitzeko eskaera ezeztatzeko",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Erakutsi @{name}(r)en bultzadak",
   "account.unblock": "Desblokeatu @{name}",
   "account.unblock_domain": "Berriz erakutsi {domain}",
+  "account.unendorse": "Ez nabarmendu profilean",
   "account.unfollow": "Jarraitzeari utzi",
   "account.unmute": "Desmututu @{name}",
   "account.unmute_notifications": "Desmututu @{name}(r)en jakinarazpenak",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "Mututu",
   "confirmations.mute.message": "Ziur {name} mututu nahi duzula?",
   "confirmations.redraft.confirm": "Ezabatu eta berridatzi",
-  "confirmations.redraft.message": "Ziur mezu hau ezabatu eta berridatzi nahi duzula? Berari egindako erantzun, bultzada eta gogokoak galduko dira.",
+  "confirmations.redraft.message": "Ziur mezu hau ezabatu eta berridatzi nahi duzula? Gogokoak eta bultzadak galduko dira eta jaso dituen erantzunak umezurtz geratuko dira.",
+  "confirmations.reply.confirm": "Erantzun",
+  "confirmations.reply.message": "Orain erantzuteak idazten ari zaren mezua gainidatziko du. Ziur jarraitu nahi duzula?",
   "confirmations.unfollow.confirm": "Utzi jarraitzeari",
   "confirmations.unfollow.message": "Ziur {name} jarraitzeari utzi nahi diozula?",
   "embed.instructions": "Txertatu mezu hau zure webgunean beheko kodea kopatuz.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Bilaketaren emaitzak",
   "emoji_button.symbols": "Sinboloak",
   "emoji_button.travel": "Bidaiak eta tokiak",
+  "empty_column.account_timeline": "Ez dago toot-ik hemen!",
+  "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.",
+  "empty_column.domain_blocks": "Ez dago ezkutatutako domeinurik oraindik.",
+  "empty_column.favourited_statuses": "Ez duzu gogokorik oraindik. Gogokoren bat duzunean hemen agertuko da.",
+  "empty_column.favourites": "Ez du inork gogokoetara gehitu toot hau oraindik. Inork egiten duenean, hemen agertuko dira.",
+  "empty_column.follow_requests": "Ez duzu jarraitzeko eskaririk oraindik. Baten bat jasotzen duzunean, hemen agertuko da.",
   "empty_column.hashtag": "Ez dago ezer traola honetan oraindik.",
   "empty_column.home": "Zure hasierako denbora-lerroa hutsik dago! Ikusi {public} edo erabili bilaketa lehen urratsak eman eta beste batzuk aurkitzeko.",
   "empty_column.home.public_timeline": "denbora-lerro publikoa",
   "empty_column.list": "Ez dago ezer zerrenda honetan. Zerrenda honetako kideek mezu berriak argitaratzean, hemen agertuko dira.",
+  "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",
   "follow_request.authorize": "Baimendu",
   "follow_request.reject": "Ukatu",
   "getting_started.developers": "Garatzaileak",
+  "getting_started.directory": "Profil-direktorioa",
   "getting_started.documentation": "Dokumentazioa",
-  "getting_started.find_friends": "Aurkitu Twitter-eko lagunak",
   "getting_started.heading": "Menua",
   "getting_started.invite": "Gonbidatu jendea",
   "getting_started.open_source_notice": "Mastodon software librea da. Ekarpenak egin ditzakezu edo akatsen berri eman GitHub bidez: {github}.",
   "getting_started.security": "Segurtasuna",
   "getting_started.terms": "Erabilera baldintzak",
+  "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.tag_mode.all": "Hauetako guztiak",
+  "hashtag.column_settings.tag_mode.any": "Hautako edozein",
+  "hashtag.column_settings.tag_mode.none": "Hauetako bat ere ez",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Oinarrizkoa",
   "home.column_settings.show_reblogs": "Erakutsi bultzadak",
   "home.column_settings.show_replies": "Erakutsi erantzunak",
+  "introduction.federation.action": "Hurrengoa",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "Fedibertsoko beste zerbitzarietako bidalketa publikoak federatutako denbora-lerroan agertuko dira.",
+  "introduction.federation.home.headline": "Home",
+  "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.text": "Zure zerbitzari berean dauden horien mezu publikoak denbora-lerro lokalean agertuko dira.",
+  "introduction.interactions.action": "Amaitu tutoriala!",
+  "introduction.interactions.favourite.headline": "Gogokoa",
+  "introduction.interactions.favourite.text": "Toot bat geroko gorde dezakezu, eta egileari gustukoa duzula jakinarazi, hau gogoko bihurtuz.",
+  "introduction.interactions.reblog.headline": "Bultzada",
+  "introduction.interactions.reblog.text": "Beste batzuen mezuak partekatu ditzakezu zure jarraitzaileekin hauei bultzada emanez.",
+  "introduction.interactions.reply.headline": "Erantzun",
+  "introduction.interactions.reply.text": "Besteen mezuei eta zure mezuei ere erantzun diezaiekezu, eta elkarrizketa batean lotuta agertuko dira.",
+  "introduction.welcome.action": "Goazen!",
+  "introduction.welcome.headline": "Lehen urratsak",
+  "introduction.welcome.text": "Ongi etorri fedibertsora! Hemendik gutxira hainbat zerbitzarietan zehar mezuak zabaldu eta lagunekin hitz egin ahal izango duzu. Baina zerbitzari hau hainbat zerbitzarietan zehar. berezia da, hau da zure profila ostatatzen duena, ez ahaztu bere izena.",
   "keyboard_shortcuts.back": "atzera nabigatzeko",
+  "keyboard_shortcuts.blocked": "blokeatutako erabiltzaileen zerrenda irekitzeko",
   "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.direct": "mezu zuzenen zutabea irekitzeko",
   "keyboard_shortcuts.down": "zerrendan behera mugitzea",
   "keyboard_shortcuts.enter": "to open status",
   "keyboard_shortcuts.favourite": "gogoko egitea",
+  "keyboard_shortcuts.favourites": "gogokoen zerrenda irekitzeko",
+  "keyboard_shortcuts.federated": "federatutako denbora-lerroa irekitzeko",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "keyboard_shortcuts.home": "hasierako denbora-lerroa irekitzeko",
   "keyboard_shortcuts.hotkey": "Laster-tekla",
   "keyboard_shortcuts.legend": "legenda hau bistaratzea",
+  "keyboard_shortcuts.local": "denbora-lerro lokala irekitzeko",
   "keyboard_shortcuts.mention": "egilea aipatzea",
+  "keyboard_shortcuts.muted": "mutututako erabiltzaileen zerrenda irekitzeko",
+  "keyboard_shortcuts.my_profile": "zure profila irekitzeko",
+  "keyboard_shortcuts.notifications": "jakinarazpenen zutabea irekitzeko",
+  "keyboard_shortcuts.pinned": "finkatutako toot-en zerrenda irekitzeko",
+  "keyboard_shortcuts.profile": "egilearen profila irekitzeko",
   "keyboard_shortcuts.reply": "erantzutea",
+  "keyboard_shortcuts.requests": "jarraitzeko eskarien zerrenda irekitzeko",
   "keyboard_shortcuts.search": "bilaketan fokua jartzea",
+  "keyboard_shortcuts.start": "\"Menua\" zutabea irekitzeko",
   "keyboard_shortcuts.toggle_hidden": "testua erakustea/ezkutatzea abisu baten atzean",
   "keyboard_shortcuts.toot": "toot berria hastea",
   "keyboard_shortcuts.unfocus": "testua konposatzeko area / bilaketatik fokua kentzea",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Ez aurkitua",
   "missing_indicator.sublabel": "Baliabide hau ezin izan da aurkitu",
   "mute_modal.hide_notifications": "Ezkutatu erabiltzaile honen jakinarazpenak?",
+  "navigation_bar.apps": "Mugikorrerako aplikazioak",
   "navigation_bar.blocks": "Blokeatutako erabiltzaileak",
   "navigation_bar.community_timeline": "Denbora-lerro lokala",
+  "navigation_bar.compose": "Idatzi toot berria",
   "navigation_bar.direct": "Mezu zuzenak",
   "navigation_bar.discover": "Aurkitu",
   "navigation_bar.domain_blocks": "Ezkutatutako domeinuak",
   "navigation_bar.edit_profile": "Aldatu profila",
   "navigation_bar.favourites": "Gogokoak",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Mutututako hitzak",
   "navigation_bar.follow_requests": "Jarraitzeko eskariak",
   "navigation_bar.info": "Instantzia honi buruz",
   "navigation_bar.keyboard_shortcuts": "Laster-teklak",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Ziur zure jakinarazpen guztiak behin betirako garbitu nahi dituzula?",
   "notifications.column_settings.alert": "Mahaigaineko jakinarazpenak",
   "notifications.column_settings.favourite": "Gogokoak:",
+  "notifications.column_settings.filter_bar.advanced": "Erakutsi kategoria guztiak",
+  "notifications.column_settings.filter_bar.category": "Iragazki azkarraren barra",
+  "notifications.column_settings.filter_bar.show": "Erakutsi",
   "notifications.column_settings.follow": "Jarraitzaile berriak:",
   "notifications.column_settings.mention": "Aipamenak:",
   "notifications.column_settings.push": "Push jakinarazpenak",
-  "notifications.column_settings.push_meta": "Gailu hau",
   "notifications.column_settings.reblog": "Bultzadak:",
   "notifications.column_settings.show": "Erakutsi zutabean",
   "notifications.column_settings.sound": "Jo soinua",
+  "notifications.filter.all": "Denak",
+  "notifications.filter.boosts": "Bultzadak",
+  "notifications.filter.favourites": "Gogokoak",
+  "notifications.filter.follows": "Jarraipenak",
+  "notifications.filter.mentions": "Aipamenak",
   "notifications.group": "{count} jakinarazpen",
-  "onboarding.done": "Egina",
-  "onboarding.next": "Hurrengoa",
-  "onboarding.page_five.public_timelines": "Denbora-lerro lokalak {domain} domeinuko guztien mezu publikoak erakusten ditu. Federatutako denbora-lerroak {domain} domeinuko edonork jarraitutakoen mezu publikoak erakusten ditu. Hauek denbora-lerro publikoak dira, jende berria ezagutzeko primerakoak.",
-  "onboarding.page_four.home": "Hasierako denbora-lerroak jarraitzen duzun jendearen mezuak erakusten ditu.",
-  "onboarding.page_four.notifications": "Jakinarazpenen  zutabeak besteek zurekin hasitako hartu-emanak erakusten ditu.",
-  "onboarding.page_one.federation": "Mastodon lotutako zerbitzari independenteez eraikitako gizarte sare bat da. Zerbitzari hauei instantzia deitzen diegu.",
-  "onboarding.page_one.full_handle": "Zure erabiltzaile-izen osoa",
-  "onboarding.page_one.handle_hint": "Hau da zure lagunei zu aurkitzeko emango zeniena.",
-  "onboarding.page_one.welcome": "Ongi etorri Mastodon-era!",
-  "onboarding.page_six.admin": "Zure instantziaren administratzailea {admin} da.",
-  "onboarding.page_six.almost_done": "Ia eginda...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "{apps} eskuragarri daude iOS, Android eta beste plataformetarako.",
-  "onboarding.page_six.github": "Mastodon software librea da. Akatsen berri eman ezakezu, ezaugarriak eskatu, edo kodea proposatu hemen:  {github}.",
-  "onboarding.page_six.guidelines": "komunitatearen gida-lerroak",
-  "onboarding.page_six.read_guidelines": "Irakurri {domain} {guidelines} mesedez!",
-  "onboarding.page_six.various_app": "mugikorrerako aplikazioak",
-  "onboarding.page_three.profile": "Editatu zure profila zure abatarra, biografia eta pantaila-izena aldatzeko. Han hobespen gehiago daude ere.",
-  "onboarding.page_three.search": "Erabili bilaketa-barra jendea aurkitzeko eta traolak begiratzeko, esaterako {illustration} edo {introductions}. Instantzia honetan ez dagoen pertsona bat bilatzeko , erabili erabiltzaile-izen osoa.",
-  "onboarding.page_two.compose": "Idatzi mezuak konposizio-zutabean. Irudiak igo ditzakezu, pribatutasun ezarpenak aldatu, eta edukiei abisuak gehitu beheko ikonoekin.",
-  "onboarding.skip": "Saltatu",
   "privacy.change": "Doitu mezuaren pribatutasuna",
   "privacy.direct.long": "Bidali aipatutako erabiltzaileei besterik ez",
   "privacy.direct.short": "Zuzena",
@@ -226,8 +268,8 @@
   "privacy.unlisted.short": "Zerrendatu gabea",
   "regeneration_indicator.label": "Kargatzen…",
   "regeneration_indicator.sublabel": "Zure hasiera-jarioa prestatzen ari da!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "relative_time.days": "{number}e",
+  "relative_time.hours": "{number}o",
   "relative_time.just_now": "orain",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
@@ -250,14 +292,17 @@
   "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}",
   "status.cancel_reblog_private": "Kendu bultzada",
   "status.cannot_reblog": "Mezu honi ezin zaio bultzada eman",
   "status.delete": "Ezabatu",
+  "status.detailed_status": "Elkarrizketaren ikuspegi xehetsua",
   "status.direct": "Mezu zuzena @{name}(r)i",
   "status.embed": "Txertatu",
   "status.favourite": "Gogokoa",
-  "status.filtered": "Filtered",
+  "status.filtered": "Iragazita",
   "status.load_more": "Kargatu gehiago",
   "status.media_hidden": "Multimedia ezkutatua",
   "status.mention": "Aipatu @{name}",
@@ -267,22 +312,27 @@
   "status.open": "Hedatu mezu hau",
   "status.pin": "Finkatu profilean",
   "status.pinned": "Finkatutako toot-a",
+  "status.read_more": "Irakurri gehiago",
   "status.reblog": "Bultzada",
   "status.reblog_private": "Bultzada jatorrizko hartzaileei",
   "status.reblogged_by": "{name}(r)en bultzada",
+  "status.reblogs.empty": "Ez dio inork bultzada eman toot honi oraindik. Inork egiten duenean, hemen agertuko dira.",
   "status.redraft": "Ezabatu eta berridatzi",
   "status.reply": "Erantzun",
   "status.replyAll": "Erantzun harian",
   "status.report": "Salatu @{name}",
   "status.sensitive_toggle": "Egin klik ikusteko",
-  "status.sensitive_warning": "Eduki hunkigarria",
+  "status.sensitive_warning": "Kontuz: Eduki hunkigarria",
   "status.share": "Partekatu",
   "status.show_less": "Erakutsi gutxiago",
   "status.show_less_all": "Erakutsi denetarik gutxiago",
   "status.show_more": "Erakutsi gehiago",
   "status.show_more_all": "Erakutsi denetarik gehiago",
+  "status.show_thread": "Erakutsi haria",
   "status.unmute_conversation": "Desmututu elkarrizketa",
   "status.unpin": "Desfinkatu profiletik",
+  "suggestions.dismiss": "Errefusatu proposamena",
+  "suggestions.header": "Hau interesatu dakizuke…",
   "tabs_bar.federated_timeline": "Federatua",
   "tabs_bar.home": "Hasiera",
   "tabs_bar.local_timeline": "Lokala",
@@ -291,9 +341,9 @@
   "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",
+  "upload_button.label": "Gehitu multimedia  (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Deskribatu ikusmen arazoak dituztenentzat",
-  "upload_form.focus": "Moztu",
+  "upload_form.focus": "Aldatu aurrebista",
   "upload_form.undo": "Ezabatu",
   "upload_progress.label": "Igotzen...",
   "video.close": "Itxi bideoa",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index ad53e9b7d3bc495b12caace0c890ceb82abcf9b1..b11d88d8757b33d3c0cc0c9786c56e163eeabaf4 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "ربات",
   "account.block": "مسدودسازی @{name}",
   "account.block_domain": "پنهان‌سازی همه چیز از سرور {domain}",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "اطلاعات زیر ممکن است نمایهٔ این کاربر را به تمامی نشان ندهد.",
   "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": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "عکس و ویدیو",
   "account.mention": "نام‌بردن از @{name}",
   "account.moved_to": "{name} منتقل شده است به:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "نشان‌دادن بازبوق‌های  @{name}",
   "account.unblock": "رفع انسداد @{name}",
   "account.unblock_domain": "رفع پنهان‌سازی از {domain}",
+  "account.unendorse": "نهفتن از نمایه",
   "account.unfollow": "پایان پیگیری",
   "account.unmute": "باصدا کردن @{name}",
   "account.unmute_notifications": "باصداکردن اعلان‌ها از طرف @{name}",
@@ -53,8 +60,8 @@
   "column.public": "نوشته‌های همه‌جا",
   "column_back_button.label": "بازگشت",
   "column_header.hide_settings": "نهفتن تنظیمات",
-  "column_header.moveLeft_settings": "انتقال ستون به چپ",
-  "column_header.moveRight_settings": "انتقال ستون به راست",
+  "column_header.moveLeft_settings": "انتقال ستون به راست",
+  "column_header.moveRight_settings": "انتقال ستون به چپ",
   "column_header.pin": "ثابت‌کردن",
   "column_header.show_settings": "نمایش تنظیمات",
   "column_header.unpin": "رهاکردن",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "بی‌صدا کن",
   "confirmations.mute.message": "آیا واقعاً می‌خواهید {name} را بی‌صدا کنید؟",
   "confirmations.redraft.confirm": "پاک‌کردن و بازنویسی",
-  "confirmations.redraft.message": "آیا واقعاً می‌خواهید این نوشته را پاک کنید و آن را از نو بنویسید؟ با این کار همهٔ پاسخ‌ها، بازبوق‌ها، و پسندیده‌شدن‌های آن از دست می‌رود.",
+  "confirmations.redraft.message": "آیا واقعاً می‌خواهید این نوشته را پاک کنید و آن را از نو بنویسید؟ با این کار بازبوق‌ها و پسندیده‌شدن‌های آن از دست می‌رود و پاسخ‌ها به آن بی‌مرجع می‌شود.",
+  "confirmations.reply.confirm": "پاسخ",
+  "confirmations.reply.message": "اگر الان پاسخ دهید، چیزی که در حال نوشتنش بودید پاک خواهد شد. آیا همین را می‌خواهید؟",
   "confirmations.unfollow.confirm": "لغو پیگیری",
   "confirmations.unfollow.message": "آیا واقعاً می‌خواهید به پیگیری از {name} پایان دهید؟",
   "embed.instructions": "برای جاگذاری این نوشته در سایت خودتان، کد زیر را کپی کنید.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "نتایج جستجو",
   "emoji_button.symbols": "نمادها",
   "emoji_button.travel": "سفر و مکان",
+  "empty_column.account_timeline": "No toots here!",
+  "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": "Profile directory",
   "getting_started.documentation": "راهنما",
-  "getting_started.find_friends": "یافتن دوستان از توییتر",
   "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",
   "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": "برای برجسته‌کردن یک نوشته در یکی از ستون‌ها",
   "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.toot": "برای آغاز یک بوق تازه",
   "keyboard_shortcuts.unfocus": "برای برداشتن توجه از نوشتن/جستجو",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "پیدا نشد",
   "missing_indicator.sublabel": "این منبع پیدا نشد",
   "mute_modal.hide_notifications": "اعلان‌های این کاربر پنهان شود؟",
+  "navigation_bar.apps": "اپ‌های موبایل",
   "navigation_bar.blocks": "کاربران مسدودشده",
   "navigation_bar.community_timeline": "نوشته‌های محلی",
-  "navigation_bar.direct": "پیغام‌های خصوصی",
+  "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.info": "اطلاعات تکمیلی",
   "navigation_bar.keyboard_shortcuts": "میان‌برهای صفحه‌کلید",
@@ -186,35 +242,21 @@
   "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.push": "اعلان‌ها از سمت سرور",
-  "notifications.column_settings.push_meta": "این دستگاه",
   "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.group": "{count} اعلان",
-  "onboarding.done": "پایان",
-  "onboarding.next": "بعدی",
-  "onboarding.page_five.public_timelines": "نوشته‌های محلی یعنی نوشته‌های همهٔ کاربران {domain}. نوشته‌های همه‌جا یعنی نوشته‌های همهٔ کسانی که کاربران {domain} آن‌ها را پی می‌گیرند. این فهرست‌های عمومی راه خوبی برای یافتن کاربران تازه هستند.",
-  "onboarding.page_four.home": "ستون «خانه» نوشته‌های کسانی را نشان می‌دهد که شما پی می‌گیرید.",
-  "onboarding.page_four.notifications": "ستون «اعلان‌ها» ارتباط‌های شما با دیگران را نشان می‌دهد.",
-  "onboarding.page_one.federation": "ماستدون شبکه‌ای از سرورهای مستقل است که با پیوستن به یکدیگر یک شبکهٔ اجتماعی بزرگ را تشکیل می‌دهند.",
-  "onboarding.page_one.full_handle": "شناسهٔ کاربری کامل شما",
-  "onboarding.page_one.handle_hint": "این چیزی است که باید به دوستان خود بگویید تا بتوانند شما را پیدا کنند.",
-  "onboarding.page_one.welcome": "به ماستدون خوش آمدید!",
-  "onboarding.page_six.admin": "نشانی مسئول سرور شما {admin} است.",
-  "onboarding.page_six.almost_done": "الان تقریباً آماده‌اید...",
-  "onboarding.page_six.appetoot": "بوق! بوق!",
-  "onboarding.page_six.apps_available": "اپ‌های گوناگونی برای اندروید، iOS، و سیستم‌های دیگر موجود است.",
-  "onboarding.page_six.github": "ماستدون یک نرم‌افزار آزاد و کدباز است. در {github} می‌توانید مشکلاتش را گزارش دهید، ویژگی‌های تازه درخواست کنید، یا در کدهایش مشارکت داشته باشید.",
-  "onboarding.page_six.guidelines": "رهنمودهای همزیستی دوستانهٔ",
-  "onboarding.page_six.read_guidelines": "لطفاً {guidelines} {domain} را بخوانید!",
-  "onboarding.page_six.various_app": "اپ‌های موبایل",
-  "onboarding.page_three.profile": "با ویرایش نمایه می‌توانید تصویر نمایه، نوشتهٔ معرفی، و نام نمایشی خود را تغییر دهید. ترجیحات دیگر شما هم آن‌جاست.",
-  "onboarding.page_three.search": "در نوار جستجو می‌توانید کاربران دیگر را بیابید یا هشتگ‌ها را ببینید، مانند {illustration} یا {introductions}. برای یافتن افرادی که روی سرورهای دیگر هستند، شناسهٔ کامل آن‌ها را بنویسید.",
-  "onboarding.page_two.compose": "در ستون «نوشتن» می‌توانید نوشته‌های تازه بنویسید. همچنین با دکمه‌های زیرش می‌توانید تصویر اضافه کنید، حریم خصوصی نوشته را تنظیم کنید، و هشدار محتوا بگذارید.",
-  "onboarding.skip": "رد کن",
   "privacy.change": "تنظیم حریم خصوصی نوشته‌ها",
   "privacy.direct.long": "تنها به کاربران نام‌برده‌شده نشان بده",
   "privacy.direct.short": "مستقیم",
@@ -250,10 +292,13 @@
   "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.block": "مسدودسازی @{name}",
   "status.cancel_reblog_private": "حذف بازبوق",
   "status.cannot_reblog": "این نوشته را نمی‌شود بازبوقید",
   "status.delete": "پاک‌کردن",
+  "status.detailed_status": "نمایش کامل گفتگو",
   "status.direct": "پیغام مستقیم به @{name}",
   "status.embed": "جاگذاری",
   "status.favourite": "پسندیدن",
@@ -267,9 +312,11 @@
   "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": "به نوشته پاسخ دهید",
@@ -281,8 +328,11 @@
   "status.show_less_all": "نمایش کمتر همه",
   "status.show_more": "نمایش",
   "status.show_more_all": "نمایش بیشتر همه",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "باصداکردن گفتگو",
   "status.unpin": "برداشتن نوشتهٔ ثابت نمایه",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "همگانی",
   "tabs_bar.home": "خانه",
   "tabs_bar.local_timeline": "محلی",
@@ -291,7 +341,7 @@
   "trends.count_by_accounts": "{count} {rawCount, plural, one {نفر نوشته است} other {نفر نوشته‌اند}}",
   "ui.beforeunload": "اگر از ماستدون خارج شوید پیش‌نویس شما پاک خواهد شد.",
   "upload_area.title": "برای بارگذاری به این‌جا بکشید",
-  "upload_button.label": "افزودن تصویر",
+  "upload_button.label": "افزودن عکس و ویدیو (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "نوشتهٔ توضیحی برای کم‌بینایان و نابینایان",
   "upload_form.focus": "بریدن لبه‌ها",
   "upload_form.undo": "حذف",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index dd7310a61046ebc4050a4ed976a4b9790a71ceec..c8d2586723b89f24451f5f8e3b0a893f3a46d5e3 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Botti",
   "account.block": "Estä @{name}",
   "account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Seuraa",
   "account.followers": "Seuraajia",
+  "account.followers.empty": "Tällä käyttäjällä ei ole vielä seuraajia.",
   "account.follows": "Seuraa",
+  "account.follows.empty": "Tämä käyttäjä ei vielä seuraa ketään.",
   "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.media": "Media",
   "account.mention": "Mainitse @{name}",
   "account.moved_to": "{name} on muuttanut instanssiin:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Näytä buustaukset käyttäjältä @{name}",
   "account.unblock": "Salli @{name}",
   "account.unblock_domain": "Näytä {domain}",
+  "account.unendorse": "Poista suosittelu profiilistasi",
   "account.unfollow": "Lakkaa seuraamasta",
   "account.unmute": "Poista käyttäjän @{name} mykistys",
   "account.unmute_notifications": "Poista mykistys käyttäjän @{name} ilmoituksilta",
@@ -59,7 +66,7 @@
   "column_header.show_settings": "Näytä asetukset",
   "column_header.unpin": "Poista kiinnitys",
   "column_subheading.settings": "Asetukset",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Vain media",
   "compose_form.direct_message_warning": "Tämä tuuttaus näkyy vain mainituille käyttäjille.",
   "compose_form.direct_message_warning_learn_more": "Lisätietoja",
   "compose_form.hashtag_warning": "Tämä tuuttaus ei näy hashtag-hauissa, koska se on listaamaton. Hashtagien avulla voi hakea vain julkisia tuuttauksia.",
@@ -84,8 +91,10 @@
   "confirmations.domain_block.message": "Haluatko aivan varmasti estää koko verkko-osoitteen {domain}? Useimmiten jokunen kohdistettu esto ja mykistys riittää, ja se on suositeltavampi tapa toimia.",
   "confirmations.mute.confirm": "Mykistä",
   "confirmations.mute.message": "Haluatko varmasti mykistää käyttäjän {name}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
+  "confirmations.redraft.confirm": "Poista & palauta muokattavaksi",
   "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": "Vastaa",
+  "confirmations.reply.message": "Jos vastaat nyt, vastaus korvaa tällä hetkellä työstämäsi viestin. Oletko varma, että haluat jatkaa?",
   "confirmations.unfollow.confirm": "Lakkaa seuraamasta",
   "confirmations.unfollow.message": "Haluatko varmasti lakata seuraamasta käyttäjää {name}?",
   "embed.instructions": "Upota statuspäivitys sivullesi kopioimalla alla oleva koodi.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Hakutulokset",
   "emoji_button.symbols": "Symbolit",
   "emoji_button.travel": "Matkailu",
+  "empty_column.account_timeline": "No toots here!",
+  "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ä.",
+  "empty_column.domain_blocks": "Yhtään verkko-osoitetta ei ole vielä piilotettu.",
+  "empty_column.favourited_statuses": "Et ole vielä lisännyt tuuttauksia suosikkeihisi. Kun teet niin, tuuttaus näkyy tässä.",
+  "empty_column.favourites": "Kukaan ei ole vielä lisännyt tätä tuuttausta suosikkeihinsa. Kun joku tekee niin, näkyy kyseinen henkilö tässä.",
+  "empty_column.follow_requests": "Sinulla ei ole vielä seurauspyyntöjä. Kun saat sellaisen, näkyy se tässä.",
   "empty_column.hashtag": "Tällä hashtagilla ei ole vielä mitään.",
   "empty_column.home": "Kotiaikajanasi on tyhjä! {public} ja hakutoiminto auttavat alkuun ja kohtaamaan muita käyttäjiä.",
   "empty_column.home.public_timeline": "yleinen aikajana",
   "empty_column.list": "Lista on vielä tyhjä. Listan jäsenten julkaisemat tilapäivitykset tulevat tähän näkyviin.",
+  "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ä",
   "follow_request.authorize": "Valtuuta",
   "follow_request.reject": "Hylkää",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Kehittäjille",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Aloitus",
-  "getting_started.invite": "Invite people",
+  "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": "Security",
-  "getting_started.terms": "Terms of service",
+  "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_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",
+  "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ä",
   "keyboard_shortcuts.boost": "buustaa",
   "keyboard_shortcuts.column": "siirrä fokus tietyn sarakkeen tilapäivitykseen",
   "keyboard_shortcuts.compose": "siirry tekstinsyöttöön",
   "keyboard_shortcuts.description": "Kuvaus",
+  "keyboard_shortcuts.direct": "avaa pikaviestisarake",
   "keyboard_shortcuts.down": "siirry listassa alaspäin",
   "keyboard_shortcuts.enter": "avaa tilapäivitys",
   "keyboard_shortcuts.favourite": "tykkää",
+  "keyboard_shortcuts.favourites": "avaa lista suosikeista",
+  "keyboard_shortcuts.federated": "avaa yleinen aikajana",
   "keyboard_shortcuts.heading": "Näppäinkomennot",
+  "keyboard_shortcuts.home": "avaa kotiaikajana",
   "keyboard_shortcuts.hotkey": "Pikanäppäin",
   "keyboard_shortcuts.legend": "näytä tämä selite",
+  "keyboard_shortcuts.local": "avaa paikallinen aikajana",
   "keyboard_shortcuts.mention": "mainitse julkaisija",
+  "keyboard_shortcuts.muted": "avaa lista mykistetyistä käyttäjistä",
+  "keyboard_shortcuts.my_profile": "avaa profiilisi",
+  "keyboard_shortcuts.notifications": "avaa ilmoitukset-sarake",
+  "keyboard_shortcuts.pinned": "avaa lista kiinnitetyistä tuuttauksista",
+  "keyboard_shortcuts.profile": "avaa kirjoittajan profiili",
   "keyboard_shortcuts.reply": "vastaa",
+  "keyboard_shortcuts.requests": "avaa lista seurauspyynnöistä",
   "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.toot": "ala kirjoittaa uutta tuuttausta",
   "keyboard_shortcuts.unfocus": "siirry pois tekstikentästä tai hakukentästä",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Ei löytynyt",
   "missing_indicator.sublabel": "Tätä resurssia ei löytynyt",
   "mute_modal.hide_notifications": "Piilota tältä käyttäjältä tulevat ilmoitukset?",
+  "navigation_bar.apps": "Mobiiliapplikaatiot",
   "navigation_bar.blocks": "Estetyt käyttäjät",
   "navigation_bar.community_timeline": "Paikallinen aikajana",
+  "navigation_bar.compose": "Kirjoita uusi tuuttaus",
   "navigation_bar.direct": "Viestit",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Piilotetut verkkotunnukset",
   "navigation_bar.edit_profile": "Muokkaa profiilia",
   "navigation_bar.favourites": "Suosikit",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Mykistetyt sanat",
   "navigation_bar.follow_requests": "Seuraamispyynnöt",
   "navigation_bar.info": "Tietoa tästä instanssista",
   "navigation_bar.keyboard_shortcuts": "Näppäinkomennot",
@@ -177,7 +233,7 @@
   "navigation_bar.pins": "Kiinnitetyt tuuttaukset",
   "navigation_bar.preferences": "Asetukset",
   "navigation_bar.public_timeline": "Yleinen aikajana",
-  "navigation_bar.security": "Security",
+  "navigation_bar.security": "Tunnukset",
   "notification.favourite": "{name} tykkäsi tilastasi",
   "notification.follow": "{name} seurasi sinua",
   "notification.mention": "{name} mainitsi sinut",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Haluatko varmasti poistaa kaikki ilmoitukset pysyvästi?",
   "notifications.column_settings.alert": "Työpöytäilmoitukset",
   "notifications.column_settings.favourite": "Tykkäykset:",
+  "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": "Uudet seuraajat:",
   "notifications.column_settings.mention": "Maininnat:",
   "notifications.column_settings.push": "Push-ilmoitukset",
-  "notifications.column_settings.push_meta": "Tämä laite",
   "notifications.column_settings.reblog": "Buustit:",
   "notifications.column_settings.show": "Näytä sarakkeessa",
   "notifications.column_settings.sound": "Äänimerkki",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifications",
-  "onboarding.done": "Valmis",
-  "onboarding.next": "Seuraava",
-  "onboarding.page_five.public_timelines": "Paikallisella aikajanalla näytetään instanssin {domain} kaikkien käyttäjien julkiset julkaisut. Yleisellä aikajanalla näytetään kaikkien instanssin {domain} käyttäjien seuraamien käyttäjien julkiset julkaisut. Nämä julkiset aikajanat ovat loistavia paikkoja löytää uusia ihmisiä.",
-  "onboarding.page_four.home": "Kotiaikajanalla näytetään seuraamiesi ihmisten julkaisut.",
-  "onboarding.page_four.notifications": "Ilmoitukset-sarakkeessa näytetään muiden sinuun liittyvä toiminta.",
-  "onboarding.page_one.federation": "Mastodon on usean itsenäisen palvelimen muodostama yhteisöpalvelu. Näitä palvelimia kutsutaan instansseiksi.",
-  "onboarding.page_one.full_handle": "Koko käyttäjänimesi",
-  "onboarding.page_one.handle_hint": "Tällä nimellä ystäväsi löytävät sinut.",
-  "onboarding.page_one.welcome": "Tervetuloa Mastodoniin!",
-  "onboarding.page_six.admin": "Instanssin ylläpitäjä on {admin}.",
-  "onboarding.page_six.almost_done": "Melkein valmista...",
-  "onboarding.page_six.appetoot": "Tuuttailun iloa!",
-  "onboarding.page_six.apps_available": "{apps} on saatavilla iOS:lle, Androidille ja muille alustoille.",
-  "onboarding.page_six.github": "Mastodon on ilmainen, vapaan lähdekoodin ohjelma. Voit raportoida bugeja, ehdottaa ominaisuuksia tai osallistua kehittämiseen GitHubissa: {github}.",
-  "onboarding.page_six.guidelines": "yhteisön säännöt",
-  "onboarding.page_six.read_guidelines": "Ole hyvä ja lue {domain}:n {guidelines}!",
-  "onboarding.page_six.various_app": "mobiilisovellukset",
-  "onboarding.page_three.profile": "Voit muuttaa profiilikuvaasi, esittelyäsi ja nimimerkkiäsi sekä muita asetuksia muokkaamalla profiiliasi.",
-  "onboarding.page_three.search": "Etsi ihmisiä ja hashtageja (esimerkiksi {illustration} tai {introductions}) hakukentän avulla. Jos haet toista instanssia käyttävää henkilöä, käytä hänen koko käyttäjänimeään.",
-  "onboarding.page_two.compose": "Kirjoita julkaisuja kirjoitussarakkeessa. Voit ladata kuvia, vaihtaa näkyvyysasetuksia ja lisätä sisältövaroituksia alla olevista painikkeista.",
-  "onboarding.skip": "Ohita",
   "privacy.change": "Säädä tuuttauksen näkyvyyttä",
   "privacy.direct.long": "Julkaise vain mainituille käyttäjille",
   "privacy.direct.short": "Suora viesti",
@@ -250,14 +292,17 @@
   "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.delete": "Poista",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Viesti käyttäjälle @{name}",
   "status.embed": "Upota",
   "status.favourite": "Tykkää",
-  "status.filtered": "Filtered",
+  "status.filtered": "Suodatettu",
   "status.load_more": "Lataa lisää",
   "status.media_hidden": "Media piilotettu",
   "status.mention": "Mainitse @{name}",
@@ -267,10 +312,12 @@
   "status.open": "Laajenna tilapäivitys",
   "status.pin": "Kiinnitä profiiliin",
   "status.pinned": "Kiinnitetty tuuttaus",
+  "status.read_more": "Näytä enemmän",
   "status.reblog": "Buustaa",
   "status.reblog_private": "Buustaa alkuperäiselle yleisölle",
   "status.reblogged_by": "{name} buustasi",
-  "status.redraft": "Delete & re-draft",
+  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
+  "status.redraft": "Poista & palauta muokattavaksi",
   "status.reply": "Vastaa",
   "status.replyAll": "Vastaa ketjuun",
   "status.report": "Raportoi @{name}",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Näytä vähemmän kaikista",
   "status.show_more": "Näytä lisää",
   "status.show_more_all": "Näytä lisää kaikista",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Poista keskustelun mykistys",
   "status.unpin": "Irrota profiilista",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Yleinen",
   "tabs_bar.home": "Koti",
   "tabs_bar.local_timeline": "Paikallinen",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 41cea6a82894bd3a007ae329c101722240345eb3..7628968879244b9e21781418621b6cce8727c4b8 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Ajouter ou retirer des listes",
   "account.badges.bot": "Bot",
   "account.block": "Bloquer @{name}",
   "account.block_domain": "Tout masquer venant de {domain}",
@@ -7,11 +8,16 @@
   "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.follows": "Abonnements",
+  "account.follows.empty": "Cet utilisateur 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.moved_to": "{name} a déménagé vers :",
@@ -21,16 +27,17 @@
   "account.posts": "Pouets",
   "account.posts_with_replies": "Pouets et réponses",
   "account.report": "Signaler",
-  "account.requested": "En attente d'approbation. Cliquez pour annuler la requête",
+  "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_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_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 non attendue 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.",
@@ -60,9 +67,9 @@
   "column_header.unpin": "Retirer",
   "column_subheading.settings": "Paramètres",
   "community.column_settings.media_only": "Média uniquement",
-  "compose_form.direct_message_warning": "Ce pouet sera uniquement envoyé qu'aux personnes mentionnées. Cependant, l'administration de votre instance et des instances réceptrices pourront inspecter ce message.",
+  "compose_form.direct_message_warning": "Ce pouet sera uniquement envoyé aux personnes mentionnées. Cependant, l’administration de votre instance et des instances réceptrices pourront inspecter ce message.",
   "compose_form.direct_message_warning_learn_more": "En savoir plus",
-  "compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur \"non-listé\". Seuls les pouets avec une visibilité \"publique\" peuvent être recherchés par hashtag.",
+  "compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur \"non listé\". Seuls les pouets avec une visibilité \"publique\" peuvent être recherchés par hashtag.",
   "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 ?",
@@ -71,7 +78,7 @@
   "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.unmarked": "Le texte n’est pas caché",
   "compose_form.spoiler_placeholder": "Écrivez ici votre avertissement",
   "confirmation_modal.cancel": "Annuler",
   "confirmations.block.confirm": "Bloquer",
@@ -81,11 +88,13 @@
   "confirmations.delete_list.confirm": "Supprimer",
   "confirmations.delete_list.message": "Êtes-vous sûr 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 vos lignes de temps publiques, ni dans vos notifications. Vos suiveurs utilisant ce domaine seront retirés.",
+  "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",
   "confirmations.mute.message": "Confirmez-vous le masquage de {name} ?",
   "confirmations.redraft.confirm": "Effacer et ré-écrire",
-  "confirmations.redraft.message": "Êtes vous sûr de vouloir effacer ce statut pour le ré-écrire ? Vous perdrez toutes ses réponses, ses repartages et ses mises en favori.",
+  "confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le ré-écrire ? Ses partages ainsi que ses mises en favori seront perdu·e·s et ses réponses seront orphelines.",
+  "confirmations.reply.confirm": "Répondre",
+  "confirmations.reply.message": "Répondre maintenant écrasera le message que vous êtes en train de composer. Voulez-vous vraiment continuer ?",
   "confirmations.unfollow.confirm": "Ne plus suivre",
   "confirmations.unfollow.message": "Voulez-vous arrêter de suivre {name} ?",
   "embed.instructions": "Intégrez ce statut à votre site en copiant le code ci-dessous.",
@@ -96,7 +105,7 @@
   "emoji_button.food": "Nourriture & Boisson",
   "emoji_button.label": "Insérer un émoji",
   "emoji_button.nature": "Nature",
-  "emoji_button.not_found": "Pas d'emojis !! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Pas d’émoji !! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Objets",
   "emoji_button.people": "Personnages",
   "emoji_button.recent": "Fréquemment utilisés",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Résultats de la recherche",
   "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.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.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.",
+  "empty_column.favourited_statuses": "Vous n’avez aucun pouet favoris pour le moment. Lorsque vous en mettrez un en favori, il apparaîtra ici.",
+  "empty_column.favourites": "Personne n’a encore mis ce pouet en favori. Lorsque quelqu’un le fera, il apparaîtra ici.",
+  "empty_column.follow_requests": "Vous n’avez pas encore de demande de suivi. Lorsque vous en recevrez une, elle apparaîtra ici.",
   "empty_column.hashtag": "Il n’y a encore aucun contenu associé à ce hashtag.",
   "empty_column.home": "Vous ne suivez personne. Visitez {public} ou utilisez la recherche pour trouver d’autres personnes à suivre.",
   "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 publierons de nouveaux statuts, ils apparaîtront ici.",
+  "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.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.directory": "Annuaire des profils",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Trouver des amis depuis Twitter",
   "getting_started.heading": "Pour commencer",
   "getting_started.invite": "Inviter des gens",
   "getting_started.open_source_notice": "Mastodon est un logiciel libre. Vous pouvez contribuer et envoyer vos commentaires et rapports de bogues via {github} sur GitHub.",
   "getting_started.security": "Sécurité",
   "getting_started.terms": "Conditions d’utilisation",
+  "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.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",
   "home.column_settings.basic": "Basique",
   "home.column_settings.show_reblogs": "Afficher les partages",
   "home.column_settings.show_replies": "Afficher les réponses",
+  "introduction.federation.action": "Suivant",
+  "introduction.federation.federated.headline": "Federated",
+  "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.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.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.reblog.headline": "Repartager",
+  "introduction.interactions.reblog.text": "Vous pouvez partager les pouets d'autres personnes avec vos suiveurs 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.column": "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.favourites": "pour ouvrir une liste de favoris",
+  "keyboard_shortcuts.federated": "pour ouvrir le fil public global",
   "keyboard_shortcuts.heading": "Raccourcis clavier",
+  "keyboard_shortcuts.home": "pour ouvrir l’accueil",
   "keyboard_shortcuts.hotkey": "Raccourci",
   "keyboard_shortcuts.legend": "pour afficher cette légende",
-  "keyboard_shortcuts.mention": "pour mentionner l'auteur",
+  "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.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",
+  "keyboard_shortcuts.profile": "pour ouvrir le profil de l’auteur·rice",
   "keyboard_shortcuts.reply": "pour répondre",
+  "keyboard_shortcuts.requests": "pour ouvrir la liste de demandes de suivi",
   "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.toot": "pour démarrer un tout nouveau pouet",
   "keyboard_shortcuts.unfocus": "pour recentrer composer textarea/search",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Non trouvé",
   "missing_indicator.sublabel": "Ressource introuvable",
   "mute_modal.hide_notifications": "Masquer les notifications de cette personne ?",
+  "navigation_bar.apps": "Applications mobiles",
   "navigation_bar.blocks": "Comptes bloqués",
   "navigation_bar.community_timeline": "Fil public local",
+  "navigation_bar.compose": "Rédiger un nouveau toot",
   "navigation_bar.direct": "Messages directs",
   "navigation_bar.discover": "Découvrir",
   "navigation_bar.domain_blocks": "Domaines cachés",
   "navigation_bar.edit_profile": "Modifier le profil",
   "navigation_bar.favourites": "Favoris",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Mots silenciés",
   "navigation_bar.follow_requests": "Demandes de suivi",
   "navigation_bar.info": "Plus d’informations",
   "navigation_bar.keyboard_shortcuts": "Raccourcis-clavier",
@@ -186,44 +242,30 @@
   "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.show": "Afficher",
   "notifications.column_settings.follow": "Nouveaux⋅elles abonné⋅e·s :",
   "notifications.column_settings.mention": "Mentions :",
   "notifications.column_settings.push": "Notifications",
-  "notifications.column_settings.push_meta": "Cet appareil",
   "notifications.column_settings.reblog": "Partages :",
   "notifications.column_settings.show": "Afficher dans la colonne",
   "notifications.column_settings.sound": "Émettre un son",
+  "notifications.filter.all": "Tout",
+  "notifications.filter.boosts": "Repartages",
+  "notifications.filter.favourites": "Favoris",
+  "notifications.filter.follows": "Suiveurs",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifications",
-  "onboarding.done": "Effectué",
-  "onboarding.next": "Suivant",
-  "onboarding.page_five.public_timelines": "Le fil public global affiche les messages de toutes les personnes suivies par les membres de {domain}. Le fil public local est identique, mais se limite aux membres de {domain}.",
-  "onboarding.page_four.home": "L’accueil affiche les messages des personnes que vous suivez.",
-  "onboarding.page_four.notifications": "La colonne de notification vous avertit lors d'une interaction avec vous.",
-  "onboarding.page_one.federation": "Mastodon est un réseau de serveurs indépendants qui se joignent pour former un réseau social plus vaste. Nous appelons ces serveurs des instances.",
-  "onboarding.page_one.full_handle": "Votre identifiant complet",
-  "onboarding.page_one.handle_hint": "C'est ce que vos amis devront rechercher.",
-  "onboarding.page_one.welcome": "Bienvenue sur Mastodon !",
-  "onboarding.page_six.admin": "L’administrateur⋅ice de votre instance est {admin}.",
-  "onboarding.page_six.almost_done": "Nous y sommes presque…",
-  "onboarding.page_six.appetoot": "Bon appouétit !",
-  "onboarding.page_six.apps_available": "De nombreuses {apps} sont disponibles pour iOS, Android et autres.",
-  "onboarding.page_six.github": "Mastodon est un logiciel libre, gratuit et open-source. Vous pouvez rapporter des bogues, suggérer des fonctionnalités, ou contribuer à son développement sur {github}.",
-  "onboarding.page_six.guidelines": "règles de la communauté",
-  "onboarding.page_six.read_guidelines": "S’il vous plaît, n’oubliez pas de lire les {guidelines} !",
-  "onboarding.page_six.various_app": "applications mobiles",
-  "onboarding.page_three.profile": "Modifiez votre profil pour changer votre avatar, votre description ainsi que votre nom. Vous y trouverez également d’autres préférences.",
-  "onboarding.page_three.search": "Utilisez la barre de recherche pour trouver des utilisateur⋅ice⋅s ou regardez des hashtags tels que {illustration} et {introductions}. Pour trouver quelqu’un qui n’est pas sur cette instance, utilisez son identifiant complet.",
-  "onboarding.page_two.compose": "Écrivez depuis la colonne de composition. Vous pouvez ajouter des images, changer les réglages de confidentialité, et ajouter des avertissements de contenu (Content Warning) grâce aux icônes en dessous.",
-  "onboarding.skip": "Passer",
   "privacy.change": "Ajuster la confidentialité du message",
-  "privacy.direct.long": "N'envoyer qu'aux personnes mentionnées",
+  "privacy.direct.long": "N’envoyer qu’aux personnes mentionnées",
   "privacy.direct.short": "Direct",
   "privacy.private.long": "Seul⋅e⋅s vos abonné⋅e⋅s verront vos statuts",
   "privacy.private.short": "Abonné⋅e⋅s uniquement",
   "privacy.public.long": "Afficher dans les fils publics",
   "privacy.public.short": "Public",
   "privacy.unlisted.long": "Ne pas afficher dans les fils publics",
-  "privacy.unlisted.short": "Non-listé",
+  "privacy.unlisted.short": "Non listé",
   "regeneration_indicator.label": "Chargement…",
   "regeneration_indicator.sublabel": "Le flux de votre page principale est en cours de préparation !",
   "relative_time.days": "{number} j",
@@ -233,8 +275,8 @@
   "relative_time.seconds": "{number} s",
   "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érateurs de votre instance. Vous pouvez expliquer pourquoi vous signalez le compte ci-dessous :",
+  "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.placeholder": "Commentaires additionnels",
   "report.submit": "Envoyer",
   "report.target": "Signalement",
@@ -250,14 +292,17 @@
   "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.cancel_reblog_private": "Dé-booster",
   "status.cannot_reblog": "Cette publication ne peut être boostée",
   "status.delete": "Effacer",
+  "status.detailed_status": "Vue détaillée de la conversation",
   "status.direct": "Envoyer un message direct à @{name}",
   "status.embed": "Intégrer",
   "status.favourite": "Ajouter aux favoris",
-  "status.filtered": "Filtered",
+  "status.filtered": "Filtré",
   "status.load_more": "Charger plus",
   "status.media_hidden": "Média caché",
   "status.mention": "Mentionner",
@@ -267,9 +312,11 @@
   "status.open": "Déplier ce statut",
   "status.pin": "Épingler sur le profil",
   "status.pinned": "Pouet épinglé",
+  "status.read_more": "En savoir plus",
   "status.reblog": "Partager",
-  "status.reblog_private": "Booster vers l'audience originale",
+  "status.reblog_private": "Booster vers l’audience originale",
   "status.reblogged_by": "{name} a partagé :",
+  "status.reblogs.empty": "Personne n’a encore partagé ce pouet. Lorsque quelqu’un le fera, il apparaîtra ici.",
   "status.redraft": "Effacer et ré-écrire",
   "status.reply": "Répondre",
   "status.replyAll": "Répondre au fil",
@@ -281,23 +328,26 @@
   "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.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.…",
   "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",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} discutent",
+  "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",
-  "upload_form.description": "Décrire pour les malvoyants",
-  "upload_form.focus": "Recadrer",
+  "upload_button.label": "Joindre un média (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_form.description": "Décrire pour les malvoyant·e·s",
+  "upload_form.focus": "Modifier l’aperçu",
   "upload_form.undo": "Supprimer",
   "upload_progress.label": "Envoi en cours…",
   "video.close": "Fermer la vidéo",
-  "video.exit_fullscreen": "Quitter plein écran",
+  "video.exit_fullscreen": "Quitter le plein écran",
   "video.expand": "Agrandir la vidéo",
   "video.fullscreen": "Plein écran",
   "video.hide": "Masquer la vidéo",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index ff817d681f443eca1a164bd7a11841bdeeac5107..c1ece163d7e09de2435e47c2e68a011502589288 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Engadir ou Eliminar das listas",
   "account.badges.bot": "Bot",
   "account.block": "Bloquear @{name}",
   "account.block_domain": "Ocultar calquer contido de {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Seguir",
   "account.followers": "Seguidoras",
+  "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.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.",
   "account.media": "Medios",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} marchou a:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Mostrar repeticións de @{name}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Non ocultar {domain}",
+  "account.unendorse": "Non mostrar no perfil",
   "account.unfollow": "Non seguir",
   "account.unmute": "Non acalar @{name}",
   "account.unmute_notifications": "Desbloquear as notificacións de @{name}",
@@ -59,9 +66,9 @@
   "column_header.show_settings": "Mostras axustes",
   "column_header.unpin": "Soltar",
   "column_subheading.settings": "Axustes",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Só medios",
   "compose_form.direct_message_warning": "Este toot enviarase só as usuarias mencionadas. Porén, a súa proveedora de internet e calquera das instancias receptoras poderían examinar esta mensaxe.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "compose_form.direct_message_warning_learn_more": "Coñecer máis",
   "compose_form.hashtag_warning": "Esta mensaxe non será listada baixo ningunha etiqueta xa que está marcada como non listada. Só os toots públicos poden buscarse por etiquetas.",
   "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",
@@ -84,14 +91,16 @@
   "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.",
   "confirmations.mute.confirm": "Acalar",
   "confirmations.mute.message": "Está segura de que quere acalar a {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.redraft.confirm": "Eliminar e reescribir",
+  "confirmations.redraft.message": "Está segura de querer eliminar este estado e voltalo a escribir? Perderá réplicas e favoritas, e as respostas ao orixinal quedarán orfas.",
+  "confirmations.reply.confirm": "Respostar",
+  "confirmations.reply.message": "Respostando agora sobreescribirá a mensaxe que está a compoñer. Segura de querer proceder?",
   "confirmations.unfollow.confirm": "Deixar de seguir",
   "confirmations.unfollow.message": "Quere deixar de seguir a {name}?",
   "embed.instructions": "Copie o código inferior para incrustar no seu sitio web este estado.",
   "embed.preview": "Así será mostrado:",
   "emoji_button.activity": "Actividade",
-  "emoji_button.custom": "Personalizado",
+  "emoji_button.custom": "Persoalizado",
   "emoji_button.flags": "Marcas",
   "emoji_button.food": "Comida e Bebida",
   "emoji_button.label": "Insertar emoji",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Resultados da busca",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viaxes e Lugares",
+  "empty_column.account_timeline": "Sen toots por aquí!",
+  "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í.",
+  "empty_column.domain_blocks": "Aínda non  ocultou ningún dominio.",
+  "empty_column.favourited_statuses": "Aínda non ten toots favoritos. Cando favoreza algún, aparecerá aquí.",
+  "empty_column.favourites": "Ninguén favoreceu este toot polo momento. Cando o faga alguén, aparecerán aquí.",
+  "empty_column.follow_requests": "Non ten peticións de seguimento. Cando reciba unha, mostrarase aquí.",
   "empty_column.hashtag": "Aínda non hai nada con esta etiqueta.",
   "empty_column.home": "A súa liña temporal de inicio está baldeira! Visite {public} ou utilice a busca para atopar outras usuarias.",
   "empty_column.home.public_timeline": "a liña temporal pública",
   "empty_column.list": "Aínda non hai nada en esta lista. Cando as usuarias incluídas na lista publiquen mensaxes, aparecerán aquí.",
+  "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",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rexeitar",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Desenvolvedoras",
+  "getting_started.directory": "Directorio do perfil",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Comezando",
-  "getting_started.invite": "Invite people",
+  "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}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
+  "getting_started.security": "Seguridade",
+  "getting_started.terms": "Termos do servizo",
+  "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.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",
   "home.column_settings.basic": "Básico",
   "home.column_settings.show_reblogs": "Mostrar repeticións",
   "home.column_settings.show_replies": "Mostrar respostas",
+  "introduction.federation.action": "Seguinte",
+  "introduction.federation.federated.headline": "Federated",
+  "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.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.",
+  "introduction.interactions.action": "Rematar titorial!",
+  "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.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!",
+  "introduction.welcome.headline": "Primeiros pasos",
+  "introduction.welcome.text": "Benvida ao fediverso! Nun intre poderá difundir mensaxes e falar cos seus amigos nun gran número de servidores. Pero este servidor (dominio) é especial—hospeda o seu perfil, así que lémbreo.",
   "keyboard_shortcuts.back": "voltar atrás",
+  "keyboard_shortcuts.blocked": "abrir lista de usuarias bloqueadas",
   "keyboard_shortcuts.boost": "promover",
   "keyboard_shortcuts.column": "destacar un estado en unha das columnas",
   "keyboard_shortcuts.compose": "Foco no área de escritura",
   "keyboard_shortcuts.description": "Descrición",
+  "keyboard_shortcuts.direct": "abrir columna de mensaxes directas",
   "keyboard_shortcuts.down": "ir hacia abaixo na lista",
   "keyboard_shortcuts.enter": "abrir estado",
   "keyboard_shortcuts.favourite": "marcar como favorito",
+  "keyboard_shortcuts.favourites": "abrir lista de favoritos",
+  "keyboard_shortcuts.federated": "abrir liña temporal federada",
   "keyboard_shortcuts.heading": "Atallos do teclado",
+  "keyboard_shortcuts.home": "abrir liña temporal de inicio",
   "keyboard_shortcuts.hotkey": "Tecla de acceso directo",
   "keyboard_shortcuts.legend": "para mostrar esta lenda",
+  "keyboard_shortcuts.local": "abrir liña temporal local",
   "keyboard_shortcuts.mention": "para mencionar o autor",
+  "keyboard_shortcuts.muted": "abrir lista de usuarias acaladas",
+  "keyboard_shortcuts.my_profile": "abrir o seu perfil",
+  "keyboard_shortcuts.notifications": "abrir columna de notificacións",
+  "keyboard_shortcuts.pinned": "abrir lista de toots fixados",
+  "keyboard_shortcuts.profile": "abrir perfil da autora",
   "keyboard_shortcuts.reply": "para responder",
+  "keyboard_shortcuts.requests": "abrir lista de peticións de seguimento",
   "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.toot": "escribir un toot novo",
   "keyboard_shortcuts.unfocus": "quitar o foco do área de escritura/busca",
@@ -159,25 +213,27 @@
   "missing_indicator.label": "Non atopado",
   "missing_indicator.sublabel": "Non se puido atopar o recurso",
   "mute_modal.hide_notifications": "Esconder notificacións deste usuario?",
+  "navigation_bar.apps": "Apps móbiles",
   "navigation_bar.blocks": "Usuarias bloqueadas",
   "navigation_bar.community_timeline": "Liña temporal local",
+  "navigation_bar.compose": "Escribir novo toot",
   "navigation_bar.direct": "Mensaxes directas",
-  "navigation_bar.discover": "Discover",
+  "navigation_bar.discover": "Descubrir",
   "navigation_bar.domain_blocks": "Dominios agochados",
   "navigation_bar.edit_profile": "Editar perfil",
   "navigation_bar.favourites": "Favoritas",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Palabras acaladas",
   "navigation_bar.follow_requests": "Peticións de seguimento",
   "navigation_bar.info": "Sobre esta instancia",
   "navigation_bar.keyboard_shortcuts": "Atallos",
   "navigation_bar.lists": "Listas",
   "navigation_bar.logout": "Sair",
   "navigation_bar.mutes": "Usuarias acaladas",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Persoal",
   "navigation_bar.pins": "Mensaxes fixadas",
   "navigation_bar.preferences": "Preferencias",
   "navigation_bar.public_timeline": "Liña temporal federada",
-  "navigation_bar.security": "Security",
+  "navigation_bar.security": "Seguridade",
   "notification.favourite": "{name} marcou como favorito o seu estado",
   "notification.follow": "{name} está a seguila",
   "notification.mention": "{name} mencionoute",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Estás seguro de que queres limpar permanentemente todas as túas notificacións?",
   "notifications.column_settings.alert": "Notificacións de escritorio",
   "notifications.column_settings.favourite": "Favoritas:",
+  "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorías",
+  "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido",
+  "notifications.column_settings.filter_bar.show": "Mostrar",
   "notifications.column_settings.follow": "Novos seguidores:",
   "notifications.column_settings.mention": "Mencións:",
   "notifications.column_settings.push": "Enviar notificacións",
-  "notifications.column_settings.push_meta": "Este aparello",
   "notifications.column_settings.reblog": "Promocións:",
   "notifications.column_settings.show": "Mostrar en columna",
   "notifications.column_settings.sound": "Reproducir son",
-  "notifications.group": "{count} notifications",
-  "onboarding.done": "Feito",
-  "onboarding.next": "Seguinte",
-  "onboarding.page_five.public_timelines": "A liña de tempo local mostra as publicacións públicas de todos en {domain}. A liña de tempo federada mostra as publicacións públicas de todos os que as persoas en {domain} seguen. Estas son as Liñas de tempo públicas, unha boa forma de descubrir novas persoas.",
-  "onboarding.page_four.home": "A liña de tempo local mostra as publicacións das persoas que segues.",
-  "onboarding.page_four.notifications": "A columna de notificacións mostra cando alguén interactúa contigo.",
-  "onboarding.page_one.federation": "Mastodon é unha rede de servidores independentes que se unen para facer unha rede social máis grande. Chamamos instancias a estes servidores.",
-  "onboarding.page_one.full_handle": "O seu alcume completo",
-  "onboarding.page_one.handle_hint": "Esto é o que lle debe dicir a quen queira seguila.",
-  "onboarding.page_one.welcome": "Benvido a Mastodon!",
-  "onboarding.page_six.admin": "O administrador da túa instancia é {admin}.",
-  "onboarding.page_six.almost_done": "Case feito...",
-  "onboarding.page_six.appetoot": "Que tootes ben!",
-  "onboarding.page_six.apps_available": "Hai {apps} dispoñíbeis para iOS, Android e outras plataformas.",
-  "onboarding.page_six.github": "Mastodon é un software gratuito e de código aberto. Pode informar de erros, solicitar novas funcionalidades ou contribuír ao código en {github}.",
-  "onboarding.page_six.guidelines": "directrices da comunidade",
-  "onboarding.page_six.read_guidelines": "Por favor, le as {guidelines} do {domain}!",
-  "onboarding.page_six.various_app": "aplicacións móbiles",
-  "onboarding.page_three.profile": "Edita o teu perfil para cambiar o teu avatar, bio e nome. Alí, tamén atoparás outras preferencias.",
-  "onboarding.page_three.search": "Utilice a barra de busca para atopar xente e descubrir etiquetas, como {illustration} e {introductions}. Para atopar unha usuaria que non está en esta instancia utilice o seu enderezo completo.",
-  "onboarding.page_two.compose": "Escriba mensaxes desde a columna de composición. Pode subir imaxes, mudar as opcións de intimidade e engadir avisos sobre o contido coas iconas inferiores.",
-  "onboarding.skip": "Saltar",
+  "notifications.filter.all": "Todo",
+  "notifications.filter.boosts": "Promocións",
+  "notifications.filter.favourites": "Favoritos",
+  "notifications.filter.follows": "Seguimentos",
+  "notifications.filter.mentions": "Mencións",
+  "notifications.group": "{count} notificacións",
   "privacy.change": "Axustar a intimidade do estado",
   "privacy.direct.long": "Enviar exclusivamente as usuarias mencionadas",
   "privacy.direct.short": "Directa",
@@ -250,14 +292,17 @@
   "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.cancel_reblog_private": "Non promover",
   "status.cannot_reblog": "Esta mensaxe non pode ser promovida",
   "status.delete": "Eliminar",
+  "status.detailed_status": "Vista detallada da conversa",
   "status.direct": "Mensaxe directa @{name}",
   "status.embed": "Incrustar",
   "status.favourite": "Favorita",
-  "status.filtered": "Filtered",
+  "status.filtered": "Filtrado",
   "status.load_more": "Cargar máis",
   "status.media_hidden": "Medios ocultos",
   "status.mention": "Mencionar @{name}",
@@ -267,10 +312,12 @@
   "status.open": "Expandir este estado",
   "status.pin": "Fixar no perfil",
   "status.pinned": "Toot fixado",
+  "status.read_more": "Lea máis",
   "status.reblog": "Promover",
   "status.reblog_private": "Promover a audiencia orixinal",
   "status.reblogged_by": "{name} promoveu",
-  "status.redraft": "Delete & re-draft",
+  "status.reblogs.empty": "Ninguén promoveu este toot polo de agora. Cando alguén o faga, mostraránse aquí.",
+  "status.redraft": "Eliminar & reescribir",
   "status.reply": "Resposta",
   "status.replyAll": "Resposta a conversa",
   "status.report": "Informar @{name}",
@@ -281,19 +328,22 @@
   "status.show_less_all": "Mostrar menos para todas",
   "status.show_more": "Mostrar máis",
   "status.show_more_all": "Mostrar máis para todas",
+  "status.show_thread": "Mostrar fío",
   "status.unmute_conversation": "Non acalar a conversa",
   "status.unpin": "Despegar do perfil",
+  "suggestions.dismiss": "Rexeitar suxestión",
+  "suggestions.header": "Podería estar interesada en…",
   "tabs_bar.federated_timeline": "Federado",
   "tabs_bar.home": "Inicio",
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificacións",
   "tabs_bar.search": "Buscar",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "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",
+  "upload_button.label": "Engadir medios (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Describa para deficientes visuais",
-  "upload_form.focus": "Recortar",
+  "upload_form.focus": "Cambiar vista previa",
   "upload_form.undo": "Eliminar",
   "upload_progress.label": "Subindo...",
   "video.close": "Pechar video",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 952c3d6db0c5238e42f38117d694a9e482df97cb..e27e7f09e6c883dd75ca567d4651ed2607fec833 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "חסימת @{name}",
   "account.block_domain": "להסתיר הכל מהקהילה {domain}",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "המידע להלן עשוי להיות לא עדכני או לא שלם.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "עריכת פרופיל",
+  "account.endorse": "Feature on profile",
   "account.follow": "מעקב",
   "account.followers": "עוקבים",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "נעקבים",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "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.media": "מדיה",
   "account.mention": "אזכור של @{name}",
   "account.moved_to": "החשבון {name} הועבר אל:",
@@ -22,16 +28,17 @@
   "account.posts_with_replies": "Toots with replies",
   "account.report": "לדווח על @{name}",
   "account.requested": "בהמתנה לאישור",
-  "account.share": "לשתף את אודות @{name}",
+  "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}",
-  "account.view_full_profile": "הראה אודות מלאות",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
+  "account.view_full_profile": "הצגת פרופיל מלא",
+  "alert.unexpected.message": "אירעה שגיאה בלתי צפויה.",
+  "alert.unexpected.title": "אופס!",
   "boost_modal.combo": "ניתן להקיש {combo} כדי לדלג בפעם הבאה",
   "bundle_column_error.body": "משהו השתבש בעת הצגת הרכיב הזה.",
   "bundle_column_error.retry": "לנסות שוב",
@@ -86,6 +93,8 @@
   "confirmations.mute.message": "להשתיק את {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": "להפסיק מעקב",
   "confirmations.unfollow.message": "להפסיק מעקב אחרי {name}?",
   "embed.instructions": "ניתן להטמיע את ההודעה באתרך ע\"י העתקת הקוד שלהלן.",
@@ -104,41 +113,86 @@
   "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.community": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!",
   "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": "אין כלום בהאשתג הזה עדיין.",
   "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.notifications": "אין התראות עדיין. יאללה, הגיע הזמן להתחיל להתערבב.",
   "empty_column.public": "אין פה כלום! כדי למלא את הטור הזה אפשר לכתוב משהו, או להתחיל לעקוב אחרי אנשים מקהילות אחרות",
   "follow_request.authorize": "קבלה",
   "follow_request.reject": "דחיה",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "בואו נתחיל",
   "getting_started.invite": "Invite people",
   "getting_started.open_source_notice": "מסטודון היא תוכנה חופשית (בקוד פתוח). ניתן לתרום או לדווח על בעיות בגיטהאב: {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": "למתחילים",
   "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": "to open blocked users list",
   "keyboard_shortcuts.boost": "להדהד",
   "keyboard_shortcuts.column": "להתמקד בהודעה באחד מהטורים",
   "keyboard_shortcuts.compose": "להתמקד בתיבת חיבור ההודעות",
   "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "keyboard_shortcuts.down": "לנוע במורד הרשימה",
   "keyboard_shortcuts.enter": "to open status",
   "keyboard_shortcuts.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": "מקש קיצור",
   "keyboard_shortcuts.legend": "להציג את הפירוש",
+  "keyboard_shortcuts.local": "to open local timeline",
   "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.reply": "לענות",
+  "keyboard_shortcuts.requests": "to open follow requests list",
   "keyboard_shortcuts.search": "להתמקד בחלון החיפוש",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
   "keyboard_shortcuts.toot": "להתחיל חיצרוץ חדש",
   "keyboard_shortcuts.unfocus": "לצאת מתיבת חיבור/חיפוש",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "לא נמצא",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "להסתיר הודעות מחשבון זה?",
+  "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "חסימות",
   "navigation_bar.community_timeline": "ציר זמן מקומי",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -186,35 +242,21 @@
   "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.push": "הודעות בדחיפה",
-  "notifications.column_settings.push_meta": "מכשיר זה",
   "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.group": "{count} notifications",
-  "onboarding.done": "יציאה",
-  "onboarding.next": "הלאה",
-  "onboarding.page_five.public_timelines": "ציר הזמן המקומי מראה הודעות פומביות מכל באי קהילת {domain}. ציר הזמן העולמי מראה הודעות פומביות מאת כי מי שבאי קהילת {domain} עוקבים אחריו. אלו צירי הזמן הפומביים, דרך נהדרת לגלות אנשים חדשים.",
-  "onboarding.page_four.home": "ציר זמן הבית מראה הודעות מהנעקבים שלך.",
-  "onboarding.page_four.notifications": "טור ההתראות מראה כשמישהו מתייחס להודעות שלך.",
-  "onboarding.page_one.federation": "מסטודון היא רשת של שרתים עצמאיים מצורפים ביחד לכדי רשת חברתית אחת גדולה. אנחנו מכנים את השרתים האלו קהילות.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "ברוכים הבאים למסטודון!",
-  "onboarding.page_six.admin": "הקהילה מנוהלת בידי {admin}.",
-  "onboarding.page_six.almost_done": "כמעט סיימנו...",
-  "onboarding.page_six.appetoot": "בתותאבון!",
-  "onboarding.page_six.apps_available": "קיימים {apps} זמינים עבור אנדרואיד, אייפון ופלטפורמות נוספות.",
-  "onboarding.page_six.github": "מסטודון הוא תוכנה חופשית. ניתן לדווח על באגים, לבקש יכולות, או לתרום לקוד באתר {github}.",
-  "onboarding.page_six.guidelines": "חוקי הקהילה",
-  "onboarding.page_six.read_guidelines": "נא לקרוא את {guidelines} של {domain}!",
-  "onboarding.page_six.various_app": "יישומונים ניידים",
-  "onboarding.page_three.profile": "ץתחת 'עריכת פרופיל' ניתן להחליף את תמונת הפרופיל שלך, תיאור קצר, והשם המוצג. שם גם ניתן למצוא אפשרויות והעדפות נוספות.",
-  "onboarding.page_three.search": "בחלונית החיפוש ניתן לחפש אנשים והאשתגים, כמו למשל {illustration} או {introductions}. כדי למצוא מישהו שלא על האינסטנס המקומי, יש להשתמש בכינוי המשתמש המלא.",
-  "onboarding.page_two.compose": "הודעות כותבים מטור הכתיבה. ניתן לנעלות תמונות, לשנות הגדרות פרטיות, ולהוסיף אזהרות תוכן בעזרת האייקונים שמתחת.",
-  "onboarding.skip": "לדלג",
   "privacy.change": "שינוי פרטיות ההודעה",
   "privacy.direct.long": "הצג רק למי שהודעה זו פונה אליו",
   "privacy.direct.short": "הודעה ישירה",
@@ -250,10 +292,13 @@
   "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.delete": "מחיקה",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "הטמעה",
   "status.favourite": "חיבוב",
@@ -267,9 +312,11 @@
   "status.open": "הרחבת הודעה",
   "status.pin": "לקבע באודות",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "הדהוד",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "הודהד על ידי {name}",
+  "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": "תגובה",
   "status.replyAll": "תגובה לכולם",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "הראה יותר",
   "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "הסרת השתקת שיחה",
   "status.unpin": "לשחרר מקיבוע באודות",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "ציר זמן בין-קהילתי",
   "tabs_bar.home": "בבית",
   "tabs_bar.local_timeline": "ציר זמן מקומי",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index f8f1d0eb389df61bf285d233a50543e3fa69dcc5..71dd5319e77fc5d840c2b8d67ab97a2ddeb827dc 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Blokiraj @{name}",
   "account.block_domain": "Sakrij sve sa {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Slijedi",
   "account.followers": "Sljedbenici",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Slijedi",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "te slijedi",
   "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": "Spomeni @{name}",
   "account.moved_to": "{name} has moved to:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Show boosts from @{name}",
   "account.unblock": "Deblokiraj @{name}",
   "account.unblock_domain": "Poništi sakrivanje {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Prestani slijediti",
   "account.unmute": "Poništi utišavanje @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
@@ -86,6 +93,8 @@
   "confirmations.mute.message": "Jesi li siguran da želiš utišati {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.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Search results",
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Putovanja & Mjesta",
+  "empty_column.account_timeline": "No toots here!",
+  "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.",
+  "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": "Još ne postoji ništa s ovim hashtagom.",
   "empty_column.home": "Još ne slijediš nikoga. Posjeti {public} ili koristi tražilicu kako bi počeo i upoznao druge korisnike.",
   "empty_column.home.public_timeline": "javni 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": "Još nemaš notifikacija. Komuniciraj sa drugima kako bi započeo razgovor.",
   "empty_column.public": "Ovdje nema ništa! Napiši nešto javno, ili ručno slijedi korisnike sa drugih instanci kako bi popunio",
   "follow_request.authorize": "Autoriziraj",
   "follow_request.reject": "Odbij",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Počnimo",
   "getting_started.invite": "Invite people",
   "getting_started.open_source_notice": "Mastodon je softver otvorenog koda. Možeš pridonijeti ili prijaviti probleme na GitHubu  {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": "Osnovno",
   "home.column_settings.show_reblogs": "Pokaži boostove",
   "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": "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",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "Nije nađen",
   "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": "Blokirani korisnici",
   "navigation_bar.community_timeline": "Lokalni timeline",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Želiš li zaista obrisati sve svoje notifikacije?",
   "notifications.column_settings.alert": "Desktop notifikacije",
   "notifications.column_settings.favourite": "Favoriti:",
+  "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": "Novi sljedbenici:",
   "notifications.column_settings.mention": "Spominjanja:",
   "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
   "notifications.column_settings.reblog": "Boostovi:",
   "notifications.column_settings.show": "Prikaži u stupcu",
   "notifications.column_settings.sound": "Sviraj zvuk",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifications",
-  "onboarding.done": "Učinjeno",
-  "onboarding.next": "Sljedeće",
-  "onboarding.page_five.public_timelines": "Lokalni timeline prikazuje javne postove sviju od svakog na {domain}. Federalni timeline prikazuje javne postove svakog koga ljudi na {domain} slijede. To su Javni Timelineovi, sjajan način za otkriti nove ljude.",
-  "onboarding.page_four.home": "The home timeline prikazuje postove ljudi koje slijediš.",
-  "onboarding.page_four.notifications": "Stupac za notifikacije pokazuje poruke drugih upućene tebi.",
-  "onboarding.page_one.federation": "Mastodon čini mreža  neovisnih servera udruženih u jednu veću socialnu mrežu. Te servere nazivamo instancama.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Dobro došli na Mastodon!",
-  "onboarding.page_six.admin": "Administrator tvoje instance je {admin}.",
-  "onboarding.page_six.almost_done": "Još malo pa gotovo...",
-  "onboarding.page_six.appetoot": "Živjeli!",
-  "onboarding.page_six.apps_available": "Postoje {apps} dostupne za iOS, Android i druge platforme.",
-  "onboarding.page_six.github": "Mastodon je besplatan softver otvorenog koda. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "smjernice zajednice",
-  "onboarding.page_six.read_guidelines": "Molimo pročitaj {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobilne aplikacije",
-  "onboarding.page_three.profile": "Uredi svoj profil promjenom svog avatara, biografije, i imena. Ovdje ćeš isto tako pronaći i druge postavke.",
-  "onboarding.page_three.search": "Koristi tražilicu kako bi pronašao ljude i tražio hashtags, kao što su {illustration} i {introductions}. Kako bi pronašao osobu koja nije na ovoj instanci, upotrijebi njen pun handle.",
-  "onboarding.page_two.compose": "Piši postove u stupcu za sastavljanje. Možeš uploadati slike, promijeniti postavke privatnosti, i dodati upozorenja o sadržaju s ikonama ispod.",
-  "onboarding.skip": "Preskoči",
   "privacy.change": "Podesi status privatnosti",
   "privacy.direct.long": "Prikaži samo spomenutim korisnicima",
   "privacy.direct.short": "Direktno",
@@ -250,10 +292,13 @@
   "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.delete": "Obriši",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Označi omiljenim",
@@ -267,9 +312,11 @@
   "status.open": "Proširi ovaj status",
   "status.pin": "Pin on profile",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "Podigni",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "{name} je podigao",
+  "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": "Odgovori",
   "status.replyAll": "Odgovori na temu",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Pokaži više",
   "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Poništi utišavanje razgovora",
   "status.unpin": "Unpin from profile",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Federalni",
   "tabs_bar.home": "Dom",
   "tabs_bar.local_timeline": "Lokalno",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 1b2397f70765560e39b589bac73ab7b6b19fe168..c2842aea7b677ad42a291f4eae30a5aa759fb772 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "@{name} letiltása",
   "account.block_domain": "Minden elrejtése innen: {domain}",
@@ -7,11 +8,16 @@
   "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.edit_profile": "Profil szerkesztése",
+  "account.endorse": "Feature on profile",
   "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.media": "Média",
   "account.mention": "@{name} említése",
   "account.moved_to": "{name} átköltözött:",
@@ -26,6 +32,7 @@
   "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",
@@ -86,6 +93,8 @@
   "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?",
   "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.",
@@ -104,41 +113,86 @@
   "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",
-  "getting_started.find_friends": "Find friends from Twitter",
   "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",
   "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",
   "keyboard_shortcuts.description": "Leírás",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "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.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.unfocus": "tülk szerkesztés/keresés fókuszpontból való kivétele",
@@ -159,8 +213,10 @@
   "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",
   "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",
@@ -186,35 +242,21 @@
   "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.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.follow": "Új követők:",
   "notifications.column_settings.mention": "Megemítéseim:",
   "notifications.column_settings.push": "Push értesítések",
-  "notifications.column_settings.push_meta": "Ezen eszköz",
   "notifications.column_settings.reblog": "Rebloggolá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",
-  "onboarding.done": "Befejezve",
-  "onboarding.next": "Következő",
-  "onboarding.page_five.public_timelines": "A helyi idővonal mindenkinek a publikus posztját mutatja a(z) {domain}-n. A federált idővonal mindenki publikus posztját mutatja akit {domain} felhasználói követnek. Ezek a publikus idővonalak, nagyszerű mód új emberek megismerésére.",
-  "onboarding.page_four.home": "A hazai idővonal azon emberek posztjait mutatja akiket te követsz.",
-  "onboarding.page_four.notifications": "Az értesítések oszlop más felhasználók interakcióját veled tükrözi.",
-  "onboarding.page_one.federation": "Mastodon egy független szerverekből alkotott hálózat melyek együttműködése egy nagy szociális hálót képez. Ezeket a szervereket instanciáknak hívjuk.",
-  "onboarding.page_one.full_handle": "Teljes elérhetőséged",
-  "onboarding.page_one.handle_hint": "Ez az amit a barátaidnak mondasz ha meg akarnak keresni.",
-  "onboarding.page_one.welcome": "Üdvözölünk a Mastodon-on!",
-  "onboarding.page_six.admin": "Az instanciád adminisztrátora {admin}.",
-  "onboarding.page_six.almost_done": "Majdnem megvan...",
-  "onboarding.page_six.appetoot": "Bon Appetülk!",
-  "onboarding.page_six.apps_available": "Vannak {apps} iOS-re, Androidra és más platformokra is.",
-  "onboarding.page_six.github": "Mastodon egy szabad és nyílt-forráskódú szoftver. Jelentheted a bug-okat, kérhetsz új funkcionalitásokat vagy hozzájárulhatsz a kódhoz {github}-on.",
-  "onboarding.page_six.guidelines": "közösségi útmutató",
-  "onboarding.page_six.read_guidelines": "Kérjük olvassa el a(z) {domain}-nak a {guidelines}ját!",
-  "onboarding.page_six.various_app": "alkalmazások",
-  "onboarding.page_three.profile": "Módosítsa a profilját, hogy megváltoztassa az avatárt, bio-t vagy nevet. Ott megtalálja a többi beállítást is.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Átugrás",
   "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",
@@ -250,10 +292,13 @@
   "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ó",
   "status.delete": "Törlés",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Beágyaz",
   "status.favourite": "Kedvenc",
@@ -267,9 +312,11 @@
   "status.open": "Státusz kinagyítá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.reply": "Válasz",
   "status.replyAll": "Válaszolj a beszélgetésre",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "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",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index d2e1bf03ef5342fe84f2f00cf8ad7b44aac5fa8a..6919948874fc5e814c32a582de975eacf9eb637c 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Ô±Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ¥Õ¬ @{name}ÖŠÕ«Õ¶",
   "account.block_domain": "Թաքցնել ամենը հետեւյալ տիրույթից՝ {domain}",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "Ներքոհիշյալը կարող է ոչ ամբողջությամբ արտացոլել օգտատիրոջ էջի տվյալները։",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Ô½Õ´Õ¢Õ¡Õ£Ö€Õ¥Õ¬ Õ¡Õ¶Õ±Õ¶Õ¡Õ¯Õ¡Õ¶ Õ§Õ»Õ¨",
+  "account.endorse": "Feature on profile",
   "account.follow": "Õ€Õ¥Õ¿Õ¥Ö‚Õ¥Õ¬",
   "account.followers": "Õ€Õ¥Õ¿Õ¥Ö‚Õ¾Õ¸Õ²Õ¶Õ¥Ö€",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Õ€Õ¥Õ¿Õ¥Ö‚Õ¸Ö‚Õ´ Õ§",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "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.media": "Õ„Õ¥Õ¤Õ«Õ¡",
   "account.mention": "Õ†Õ·Õ¥Õ¬ @{name}ÖŠÕ«Õ¶",
   "account.moved_to": "{name}֊ը տեղափոխվել է՝",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Ցուցադրել @{name}֊ի տարածածները",
   "account.unblock": "Ô±ÕºÕ¡Õ¡Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ¥Õ¬ @{name}ÖŠÕ«Õ¶",
   "account.unblock_domain": "Ցուցադրել {domain} թաքցված տիրույթի գրառումները",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Õ‰Õ°Õ¥Õ¿Õ¥Ö‚Õ¥Õ¬",
   "account.unmute": "Ապալռեցնել @{name}֊ին",
   "account.unmute_notifications": "Միացնել ծանուցումները @{name}֊ից",
@@ -86,6 +93,8 @@
   "confirmations.mute.message": "Վստա՞հ ես, որ ուզում ես {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": "Ô±ÕºÕ¡Õ°Õ¥Õ¿Õ¥Ö‚Õ¥Õ¬",
   "confirmations.unfollow.message": "ÕŽÕ½Õ¿Õ¡ÕžÕ° Õ¥Õ½, Õ¸Ö€ Õ¸Ö‚Õ¦Õ¸Ö‚Õ´ Õ¥Õ½ Õ¡ÕµÕ¬Õ¥Ö‚Õ½ Õ¹Õ°Õ¥Õ¿Õ¥Ö‚Õ¥Õ¬ {name}ÖŠÕ«Õ¶Ö‰",
   "embed.instructions": "Ô±ÕµÕ½ Õ©Õ¸Ö‚Õ©Õ¨ Ö„Õ¸ Õ¯Õ¡ÕµÖ„Õ¸Ö‚Õ´ Õ¶Õ¥Ö€Õ¤Õ¶Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ Õ¯Õ¡Ö€Õ¸Õ² Õ¥Õ½ ÕºÕ¡Õ¿Õ³Õ¥Õ¶Õ¥Õ¬ Õ¶Õ¥Ö€Ö„Õ¸Õ°Õ«Õ·ÕµÕ¡Õ¬ Õ¯Õ¸Õ¤Õ¨Ö‰",
@@ -104,41 +113,86 @@
   "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.community": "Տեղական հոսքը դատա՛րկ է։ Հրապարակային մի բան գրիր շարժիչը խոդ տալու համար։",
   "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": "Ô±ÕµÕ½ ÕºÕ«Õ¿Õ¡Õ¯Õ¸Õ¾ Õ¤Õ¥Õ¼ Õ¸Õ¹Õ«Õ¶Õ¹ Õ¹Õ¯Õ¡Ö‰",
   "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.notifications": "Ոչ մի ծանուցում դեռ չունես։ Բզիր մյուսներին՝ խոսակցությունը սկսելու համար։",
   "empty_column.public": "Այստեղ բան չկա՛։ Հրապարակային մի բան գրիր կամ հետեւիր այլ հանգույցներից էակների՝ այն լցնելու համար։",
   "follow_request.authorize": "Վավերացնել",
   "follow_request.reject": "Õ„Õ¥Ö€ÕªÕ¥Õ¬",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Ô»Õ¶Õ¹ÕºÕ¥Õ½ Õ½Õ¯Õ½Õ¥Õ¬",
   "getting_started.invite": "Invite people",
   "getting_started.open_source_notice": "Մաստոդոնը բաց ելատեքստով ծրագրակազմ է։ Կարող ես ներդրում անել կամ վրեպներ զեկուցել ԳիթՀաբում՝ {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": "Õ€Õ«Õ´Õ¶Õ¡Õ¯Õ¡Õ¶",
   "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": "to open blocked users list",
   "keyboard_shortcuts.boost": "Õ¿Õ¡Ö€Õ¡Õ®Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€",
   "keyboard_shortcuts.column": "սյուներից մեկի վրա սեւեռվելու համար",
   "keyboard_shortcuts.compose": "Õ·Õ¡Ö€Õ¡Õ¤Ö€Õ´Õ¡Õ¶ Õ¿Õ«Ö€Õ¸Ö‚ÕµÕ©Õ«Õ¶ Õ½Õ¥Ö‚Õ¥Õ¼Õ¾Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€",
   "keyboard_shortcuts.description": "Õ†Õ¯Õ¡Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "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.heading": "Ստեղնաշարի կարճատներ",
+  "keyboard_shortcuts.home": "to open home timeline",
   "keyboard_shortcuts.hotkey": "Õ€Õ¡Õ¿Õ¸Ö‚Õ¯ Õ½Õ¿Õ¥Õ²Õ¶",
   "keyboard_shortcuts.legend": "այս ձեռնարկը ցուցադրելու համար",
+  "keyboard_shortcuts.local": "to open local timeline",
   "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.reply": "ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€",
+  "keyboard_shortcuts.requests": "to open follow requests list",
   "keyboard_shortcuts.search": "Õ¸Ö€Õ¸Õ¶Õ´Õ¡Õ¶ Õ¤Õ¡Õ·Õ¿Õ«Õ¶ Õ½Õ¥Ö‚Õ¥Õ¼Õ¾Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
   "keyboard_shortcuts.toot": "Õ©Õ¡Ö€Õ´ Õ©Õ¸Ö‚Õ© Õ½Õ¯Õ½Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€",
   "keyboard_shortcuts.unfocus": "տեքստի/որոնման տիրույթից ապասեւեռվելու համար",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "Չգտնվեց",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Թաքցնե՞լ ցանուցումներն այս օգտատիրոջից։",
+  "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Ô±Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ¾Õ¡Õ® Ö…Õ£Õ¿Õ¡Õ¿Õ¥Ö€Õ¥Ö€",
   "navigation_bar.community_timeline": "Տեղական հոսք",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -186,35 +242,21 @@
   "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.push": "Հրելու ծանուցումներ",
-  "notifications.column_settings.push_meta": "Ô±ÕµÕ½ Õ½Õ¡Ö€Ö„Õ¨",
   "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.group": "{count} notifications",
-  "onboarding.done": "ÕŠÕ¡Õ¿Ö€Õ¡Õ½Õ¿ Õ§",
-  "onboarding.next": "Õ€Õ¡Õ»Õ¸Ö€Õ¤",
-  "onboarding.page_five.public_timelines": "Տեղական հոսքը ցույց է տալիս {domain} տիրույթից բոլորի հրապարակային թթերը։ Դաշնային հոսքը ցույց է տալիս հրապարակային թթերը բոլորից, ում {domain} տիրույթի մարդիկ հետեւում են։ Սրանք Հրապարակային հոսքերն են՝ նոր մարդկանց բացահայտելու հրաշալի միջոց։",
-  "onboarding.page_four.home": "Հիմնական հոսքը ցույց է տալիս այն մարդկանց թթերը, ում հետեւում ես։",
-  "onboarding.page_four.notifications": "Ծանուցումների սյունը ցույց է տալիս, երբ որեւէ մեկը փոխգործակցում է հետդ։",
-  "onboarding.page_one.federation": "Մաստոդոնը անկախ սպասարկիչների ցանց է, որոնք միասնական սոցիալական ցանց են կազմում։ Մենք կոչում ենք այդ սպասարկիչները հանգույցներ։",
-  "onboarding.page_one.full_handle": "Õ”Õ¸ Õ¡Õ´Õ¢Õ¸Õ²Õ»Õ¡Õ¯Õ¡Õ¶ Ö…Õ£Õ¿Õ¡Õ¶Õ¸Ö‚Õ¶Õ¨",
-  "onboarding.page_one.handle_hint": "Սա այն է, ինչ ասելու ես ընկերներիդ՝ քեզ փնտրելու համար։",
-  "onboarding.page_one.welcome": "Բարի գալուստ Մաստոդո՜ն",
-  "onboarding.page_six.admin": "Քո հանգույցի ադմինը նա է՝ {admin}։",
-  "onboarding.page_six.almost_done": "Գրեթե պատրաստ է…",
-  "onboarding.page_six.appetoot": "Հաջողութությո՜ւն",
-  "onboarding.page_six.apps_available": "Նաեւ կան այՕՍի, Անդրոիդի եւ այլ հարթակների համար {apps}։",
-  "onboarding.page_six.github": "Մաստոդոնն ազատ ու բաց ելատեքստով ծրագրակազմ է։ Կարող ես վրեպներ զեկուցել, նոր հատկություններ հայցել կամ ներդրում անել {github}֊ում։",
-  "onboarding.page_six.guidelines": "Õ°Õ¡Õ´Õ¡ÕµÕ¶Ö„Õ« Õ¯Õ¡Õ¶Õ¸Õ¶Õ¡Õ¯Õ¡Ö€Õ£",
-  "onboarding.page_six.read_guidelines": "Ô½Õ¶Õ¤Ö€Õ¸Ö‚Õ´ Õ¥Õ¶Ö„, Õ¯Õ¡Ö€Õ¤Õ¡ {domain} Õ¿Õ«Ö€Õ¸Ö‚ÕµÕ©Õ« {guidelines}Õ¨Ö‰",
-  "onboarding.page_six.various_app": "Õ°Õ¡Õ¾Õ¥Õ¬Õ¾Õ¡Õ®Õ¶Õ¥Ö€",
-  "onboarding.page_three.profile": "Թարմացրու անձնական էջդ՝ նկարդ, կենսագրությունդ ու անունդ փոխելու համար։ Այնտեղ նաեւ այլ նախապատվություններ կգտնես։",
-  "onboarding.page_three.search": "Օգտվիր որոնման դաշտից՝ մարդկանց գտնելու կամ պիտակներին՝ օրինակ {illustration} ու {introductions}, ծանոթանալու համար։ Ոչ այս հանգույցի բնակիչներին փնտրելու համար օգտագործիր նրանց ամբողջական օգտանունը։",
-  "onboarding.page_two.compose": "Գրիր թթերդ շարադրման սյունակում։ Կարող ես նկարներ վերբեռնել, փոփոխել գաղտնիության կարգավորումները եւ բովանդակության վերաբերյալ նախազգուշացումներ ավելացնել՝ օգտվելով ներքեւի պատկերակներից։",
-  "onboarding.skip": "Բաց թողնել",
   "privacy.change": "Ô¿Õ¡Ö€Õ£Õ¡Õ¾Õ¸Ö€Õ¥Õ¬ Õ©Õ©Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ«Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨",
   "privacy.direct.long": "Ô¹Õ©Õ¥Õ¬ Õ´Õ«Õ¡ÕµÕ¶ Õ¶Õ·Õ¾Õ¡Õ® Ö…Õ£Õ¿Õ¡Õ¿Õ¥Ö€Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€",
   "privacy.direct.short": "Հասցեագրված",
@@ -250,10 +292,13 @@
   "search_results.statuses": "Toots",
   "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": "Unboost",
   "status.cannot_reblog": "Ô±ÕµÕ½ Õ©Õ¸Ö‚Õ©Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¿Õ¡Ö€Õ¡Õ®Õ¾Õ¥Õ¬",
   "status.delete": "Õ‹Õ¶Õ»Õ¥Õ¬",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Õ†Õ¥Ö€Õ¤Õ¶Õ¥Õ¬",
   "status.favourite": "Õ€Õ¡Õ¾Õ¡Õ¶Õ¥Õ¬",
@@ -267,9 +312,11 @@
   "status.open": "Ô¸Õ¶Õ¤Õ¡Ö€Õ±Õ¡Õ¯Õ¥Õ¬ Õ¡ÕµÕ½ Õ©Õ¸Ö‚Õ©Õ¨",
   "status.pin": "Ամրացնել անձնական էջում",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "Տարածել",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "{name} Õ¿Õ¡Ö€Õ¡Õ®Õ¥Õ¬ Õ§",
+  "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": "ÕŠÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Õ¬",
   "status.replyAll": "ÕŠÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Õ¬ Õ©Õ¥Õ¬Õ«Õ¶",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Ô±Õ¾Õ¥Õ¬Õ«Õ¶",
   "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Ապալռեցնել խոսակցությունը",
   "status.unpin": "Հանել անձնական էջից",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Ô´Õ¡Õ·Õ¶Õ¡ÕµÕ«Õ¶",
   "tabs_bar.home": "Õ€Õ«Õ´Õ¶Õ¡Õ¯Õ¡Õ¶",
   "tabs_bar.local_timeline": "Տեղական",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index 06045ae998f88539361e977b1bb82050d6f46f05..eed61af707cce54c55980e3ecabeec8f554ceea7 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Blokir @{name}",
   "account.block_domain": "Sembunyikan segalanya dari {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Ikuti",
   "account.followers": "Pengikut",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Mengikuti",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Mengikuti anda",
   "account.hide_reblogs": "Sembunyikan boosts dari @{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": "Balasan @{name}",
   "account.moved_to": "{name} telah pindah ke:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Tampilkan boost dari @{name}",
   "account.unblock": "Hapus blokir @{name}",
   "account.unblock_domain": "Tampilkan {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Berhenti mengikuti",
   "account.unmute": "Berhenti membisukan @{name}",
   "account.unmute_notifications": "Munculkan notifikasi dari @{name}",
@@ -86,6 +93,8 @@
   "confirmations.mute.message": "Apa anda yakin ingin membisukan {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": "Berhenti mengikuti",
   "confirmations.unfollow.message": "Apakah anda ingin berhenti mengikuti {name}?",
   "embed.instructions": "Sematkan status ini di website anda dengan menyalin kode di bawah ini.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Hasil pencarian",
   "emoji_button.symbols": "Simbol",
   "emoji_button.travel": "Tempat Wisata",
+  "empty_column.account_timeline": "No toots here!",
+  "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.",
+  "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": "Tidak ada apapun dalam hashtag ini.",
   "empty_column.home": "Linimasa anda kosong! Kunjungi {public} atau gunakan pencarian untuk memulai dan bertemu pengguna lain.",
   "empty_column.home.public_timeline": "linimasa publik",
   "empty_column.list": "Tidak ada postingan di list ini. Ketika anggota dari list ini memposting status baru, status tersebut akan tampil disini.",
+  "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": "Anda tidak memiliki notifikasi apapun. Berinteraksi dengan orang lain untuk memulai percakapan.",
   "empty_column.public": "Tidak ada apapun disini! Tulis sesuatu, atau ikuti pengguna lain dari server lain untuk mengisi ini",
   "follow_request.authorize": "Izinkan",
   "follow_request.reject": "Tolak",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Mulai",
   "getting_started.invite": "Invite people",
   "getting_started.open_source_notice": "Mastodon adalah perangkat lunak yang bersifat terbuka. Anda dapat berkontribusi atau melaporkan permasalahan/bug di Github {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": "Dasar",
   "home.column_settings.show_reblogs": "Tampilkan boost",
   "home.column_settings.show_replies": "Tampilkan balasan",
+  "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": "untuk kembali",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
   "keyboard_shortcuts.boost": "untuk menyebarkan",
   "keyboard_shortcuts.column": "untuk fokus kepada sebuah status di sebuah kolom",
   "keyboard_shortcuts.compose": "untuk fokus ke area penulisan",
   "keyboard_shortcuts.description": "Deskripsi",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "keyboard_shortcuts.down": "untuk pindah ke bawah dalam sebuah daftar",
   "keyboard_shortcuts.enter": "untuk membuka status",
   "keyboard_shortcuts.favourite": "untuk memfavoritkan",
+  "keyboard_shortcuts.favourites": "to open favourites list",
+  "keyboard_shortcuts.federated": "to open federated timeline",
   "keyboard_shortcuts.heading": "Pintasan keyboard",
+  "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": "untuk fokus mencari",
+  "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",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "Tidak ditemukan",
   "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": "Pengguna diblokir",
   "navigation_bar.community_timeline": "Linimasa lokal",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Apa anda yakin hendak menghapus semua notifikasi anda?",
   "notifications.column_settings.alert": "Notifikasi desktop",
   "notifications.column_settings.favourite": "Favorit:",
+  "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": "Pengikut baru:",
   "notifications.column_settings.mention": "Balasan:",
   "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
   "notifications.column_settings.reblog": "Boost:",
   "notifications.column_settings.show": "Tampilkan dalam kolom",
   "notifications.column_settings.sound": "Mainkan suara",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifications",
-  "onboarding.done": "Selesei",
-  "onboarding.next": "Selanjutnya",
-  "onboarding.page_five.public_timelines": "Linimasa lokal menampilkan semua postingan publik dari semua orang di {domain}. Linimasa gabungan menampilkan postingan publik dari semua orang yang diikuti oleh {domain}. Ini semua adalah Linimasa Publik, cara terbaik untuk bertemu orang lain.",
-  "onboarding.page_four.home": "Linimasa beranda menampilkan postingan dari orang-orang yang anda ikuti.",
-  "onboarding.page_four.notifications": "Kolom notifikasi menampilkan ketika seseorang berinteraksi dengan anda.",
-  "onboarding.page_one.federation": "Mastodon adalah jaringan dari beberapa server independen yang bergabung untuk membuat jejaring sosial yang besar.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Selamat datang di Mastodon!",
-  "onboarding.page_six.admin": "Admin serveer anda adalah {admin}.",
-  "onboarding.page_six.almost_done": "Hampir selesei...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Ada beberapa apl yang tersedia untuk iOS, Android, dan platform lainnya.",
-  "onboarding.page_six.github": "Mastodon adalah software open-source. Anda bisa melaporkan bug, meminta fitur, atau berkontribusi dengan kode di {github}.",
-  "onboarding.page_six.guidelines": "pedoman komunitas",
-  "onboarding.page_six.read_guidelines": "Silakan baca {guidelines} {domain}!",
-  "onboarding.page_six.various_app": "apl handphone",
-  "onboarding.page_three.profile": "Ubah profil anda untuk mengganti avatar, bio, dan nama pengguna anda. Disitu, anda juga bisa mengatur opsi lainnya.",
-  "onboarding.page_three.search": "Gunakan kolom pencarian untuk mencari orang atau melihat hashtag, seperti {illustration} dan {introductions}. Untuk mencari pengguna yang tidak berada dalam server ini, gunakan nama pengguna mereka selengkapnya.",
-  "onboarding.page_two.compose": "Tulis postingan melalui kolom posting. Anda dapat mengunggah gambar, mengganti pengaturan privasi, dan menambahkan peringatan konten dengan ikon-ikon dibawah ini.",
-  "onboarding.skip": "Lewati",
   "privacy.change": "Tentukan privasi status",
   "privacy.direct.long": "Kirim hanya ke pengguna yang disebut",
   "privacy.direct.short": "Langsung",
@@ -250,10 +292,13 @@
   "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.delete": "Hapus",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Difavoritkan",
@@ -267,9 +312,11 @@
   "status.open": "Tampilkan status ini",
   "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": "di-boost {name}",
+  "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": "Balas",
   "status.replyAll": "Balas ke semua",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Tampilkan semua",
   "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": "Gabungan",
   "tabs_bar.home": "Beranda",
   "tabs_bar.local_timeline": "Lokal",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index 5f9175c4f55b4cfa7bea7d575263c57ba048d588..b26fa6c4ab415f1456c6701a4eceb130de45e7ad 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Blokusar @{name}",
   "account.block_domain": "Hide everything from {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Sequar",
   "account.followers": "Sequanti",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Sequas",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Sequas tu",
   "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": "Mencionar @{name}",
   "account.moved_to": "{name} has moved to:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Show boosts from @{name}",
   "account.unblock": "Desblokusar @{name}",
   "account.unblock_domain": "Unhide {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Ne plus sequar",
   "account.unmute": "Ne plus celar @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
@@ -86,6 +93,8 @@
   "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.",
@@ -104,41 +113,86 @@
   "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": "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.",
+  "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": "Esas ankore nulo en ta gretovorto.",
   "empty_column.home": "Tu sequas ankore nulu. Vizitez {public} od uzez la serchilo por komencar e renkontrar altra uzeri.",
   "empty_column.home.public_timeline": "la publika tempolineo",
   "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": "Tu havas ankore nula savigo. Komunikez kun altri por debutar la konverso.",
   "empty_column.public": "Esas nulo hike! Skribez ulo publike, o manuale sequez uzeri de altra instaluri por plenigar ol.",
   "follow_request.authorize": "Yurizar",
   "follow_request.reject": "Refuzar",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Debuto",
   "getting_started.invite": "Invite people",
   "getting_started.open_source_notice": "Mastodon esas programaro kun apertita kodexo. Tu povas kontributar o signalar problemi en GitHub ye {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": "Simpla",
   "home.column_settings.show_reblogs": "Montrar repeti",
   "home.column_settings.show_replies": "Montrar respondi",
+  "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": "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",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "Ne trovita",
   "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": "Blokusita uzeri",
   "navigation_bar.community_timeline": "Lokala tempolineo",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Ka tu esas certa, ke tu volas efacar omna tua savigi?",
   "notifications.column_settings.alert": "Surtabla savigi",
   "notifications.column_settings.favourite": "Favorati:",
+  "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": "Nova sequanti:",
   "notifications.column_settings.mention": "Mencioni:",
   "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
   "notifications.column_settings.reblog": "Repeti:",
   "notifications.column_settings.show": "Montrar en kolumno",
   "notifications.column_settings.sound": "Plear sono",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifications",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
-  "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
   "privacy.change": "Aranjar privateso di mesaji",
   "privacy.direct.long": "Sendar nur a mencionata uzeri",
   "privacy.direct.short": "Direte",
@@ -250,10 +292,13 @@
   "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.delete": "Efacar",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favorizar",
@@ -267,9 +312,11 @@
   "status.open": "Detaligar ca mesajo",
   "status.pin": "Pin on profile",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "Repetar",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "{name} repetita",
+  "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": "Respondar",
   "status.replyAll": "Respondar a filo",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Montrar plue",
   "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": "Federata",
   "tabs_bar.home": "Hemo",
   "tabs_bar.local_timeline": "Lokala",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index b20263df66c30ab72a9aea790c78694b82d64b9c..1f52d37248bde2b2f067bf6efa9987c0bf20bf0c 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -1,17 +1,23 @@
 {
+  "account.add_or_remove_from_list": "Aggiungi o togli dalle liste",
   "account.badges.bot": "Bot",
   "account.block": "Blocca @{name}",
   "account.block_domain": "Nascondi tutto da {domain}",
   "account.blocked": "Bloccato",
-  "account.direct": "Direct Message @{name}",
+  "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",
   "account.follow": "Segui",
   "account.followers": "Seguaci",
+  "account.followers.empty": "Ancora nessuno segue questo utente.",
   "account.follows": "Segue",
+  "account.follows.empty": "Questo utente non segue ancora nessuno.",
   "account.follows_you": "Ti segue",
   "account.hide_reblogs": "Nascondi condivisioni da @{name}",
+  "account.link_verified_on": "La proprietà di questo link è stata controllata il {date}",
+  "account.locked_info": "Il livello di privacy di questo account è impostato a \"bloccato\". Il proprietario esamina manualmente le richieste di seguirlo.",
   "account.media": "Media",
   "account.mention": "Menziona @{name}",
   "account.moved_to": "{name} si è trasferito su:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Mostra condivisioni da @{name}",
   "account.unblock": "Sblocca @{name}",
   "account.unblock_domain": "Non nascondere {domain}",
+  "account.unendorse": "Non mettere in evidenza sul profilo",
   "account.unfollow": "Non seguire",
   "account.unmute": "Non silenziare @{name}",
   "account.unmute_notifications": "Non silenziare più le notifiche da @{name}",
@@ -49,7 +56,7 @@
   "column.lists": "Liste",
   "column.mutes": "Utenti silenziati",
   "column.notifications": "Notifiche",
-  "column.pins": "Pinned toot",
+  "column.pins": "Toot fissati in cima",
   "column.public": "Timeline federata",
   "column_back_button.label": "Indietro",
   "column_header.hide_settings": "Nascondi impostazioni",
@@ -74,11 +81,11 @@
   "compose_form.spoiler.unmarked": "Il testo non è nascosto",
   "compose_form.spoiler_placeholder": "Content warning",
   "confirmation_modal.cancel": "Annulla",
-  "confirmations.block.confirm": "Block",
+  "confirmations.block.confirm": "Blocca",
   "confirmations.block.message": "Sei sicuro di voler bloccare {name}?",
-  "confirmations.delete.confirm": "Delete",
+  "confirmations.delete.confirm": "Cancella",
   "confirmations.delete.message": "Sei sicuro di voler cancellare questo status?",
-  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.confirm": "Cancella",
   "confirmations.delete_list.message": "Sei sicuro di voler cancellare definitivamente questa lista?",
   "confirmations.domain_block.confirm": "Nascondi intero dominio",
   "confirmations.domain_block.message": "Sei davvero sicuro che vuoi bloccare l'intero {domain}? Nella maggior parte dei casi, pochi blocchi o silenziamenti mirati sono sufficienti e preferibili. Non vedrai nessun contenuto di quel dominio né nelle timeline pubbliche né nelle notifiche. I tuoi seguaci di quel dominio saranno eliminati.",
@@ -86,6 +93,8 @@
   "confirmations.mute.message": "Sei sicuro di voler silenziare {name}?",
   "confirmations.redraft.confirm": "Cancella e riscrivi",
   "confirmations.redraft.message": "Sei sicuro di voler cancellare questo stato e riscriverlo? Perderai tutte le risposte, condivisioni e preferiti.",
+  "confirmations.reply.confirm": "Rispondi",
+  "confirmations.reply.message": "Se rispondi ora, il messaggio che stai componendo sarà sovrascritto. Sei sicuro di voler continuare?",
   "confirmations.unfollow.confirm": "Smetti di seguire",
   "confirmations.unfollow.message": "Sei sicuro che non vuoi più seguire {name}?",
   "embed.instructions": "Inserisci questo status nel tuo sito copiando il codice qui sotto.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Risultati della ricerca",
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Viaggi e luoghi",
+  "empty_column.account_timeline": "Non ci sono toot qui!",
+  "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.",
+  "empty_column.domain_blocks": "Non vi sono domini nascosti.",
+  "empty_column.favourited_statuses": "Non hai ancora segnato nessun toot come apprezzato. Quando lo farai, comparirà qui.",
+  "empty_column.favourites": "Nessuno ha ancora segnato questo toot come apprezzato. Quando qualcuno lo farà, apparirà qui.",
+  "empty_column.follow_requests": "Non hai ancora ricevuto nessuna richiesta di seguirti. Quando ne arriveranno, saranno mostrate qui.",
   "empty_column.hashtag": "Non c'è ancora nessun post con questo hashtag.",
   "empty_column.home": "Non stai ancora seguendo nessuno. Visita {public} o usa la ricerca per incontrare nuove persone.",
   "empty_column.home.public_timeline": "la timeline pubblica",
-  "empty_column.list": "Non c'è niente in questo elenco ancora. Quando i membri di questo elenco postano nuovi stati, questi appariranno qui.",
+  "empty_column.list": "Non c'è ancora niente in questa lista. Quando i membri di questa lista pubblicheranno nuovi stati, appariranno qui.",
+  "empty_column.lists": "Non hai ancora nessuna lista. Quando ne creerai qualcuna, comparirà qui.",
+  "empty_column.mutes": "Non hai ancora silenziato nessun utente.",
   "empty_column.notifications": "Non hai ancora nessuna notifica. Interagisci con altri per iniziare conversazioni.",
   "empty_column.public": "Qui non c'è nulla! Scrivi qualcosa pubblicamente, o aggiungi utenti da altri server per riempire questo spazio",
   "follow_request.authorize": "Autorizza",
   "follow_request.reject": "Rifiuta",
   "getting_started.developers": "Sviluppatori",
+  "getting_started.directory": "Directory del profilo",
   "getting_started.documentation": "Documentazione",
-  "getting_started.find_friends": "Trova amici da Twitter",
   "getting_started.heading": "Come iniziare",
   "getting_started.invite": "Invita qualcuno",
   "getting_started.open_source_notice": "Mastodon è un software open source. Puoi contribuire o segnalare errori su GitHub all'indirizzo {github}.",
   "getting_started.security": "Sicurezza",
   "getting_started.terms": "Condizioni del servizio",
+  "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.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",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Semplice",
   "home.column_settings.show_reblogs": "Mostra post condivisi",
   "home.column_settings.show_replies": "Mostra risposte",
+  "introduction.federation.action": "Avanti",
+  "introduction.federation.federated.headline": "Federated",
+  "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.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",
+  "introduction.interactions.favourite.text": "Puoi salvare un toot e tenerlo per dopo, e far sapere all'autore che ti è piaciuto, segnandolo come apprezzato.",
+  "introduction.interactions.reblog.headline": "Condividi",
+  "introduction.interactions.reblog.text": "Con la condivisione puoi segnalare i toot di altre persone ai tuoi seguaci .",
+  "introduction.interactions.reply.headline": "Rispondi",
+  "introduction.interactions.reply.text": "Puoi rispondere ai toot, sia a quelli di altri sia ai tuoi, e i toot saranno collegati a formare una conversazione.",
+  "introduction.welcome.action": "Andiamo!",
+  "introduction.welcome.headline": "Primi passi",
+  "introduction.welcome.text": "Benvenuto/a nel fediverse! Tra poco potrai inviare messaggi e parlare con i tuoi amici su una grande varietà di server. Ma questo server, {domain}, è speciale: ospita il tuo profilo, quindi ricordati il suo nome.",
   "keyboard_shortcuts.back": "per tornare indietro",
+  "keyboard_shortcuts.blocked": "per aprire l'elenco degli utenti bloccati",
   "keyboard_shortcuts.boost": "per condividere",
   "keyboard_shortcuts.column": "per portare il focus su uno status in una delle colonne",
   "keyboard_shortcuts.compose": "per portare il focus nell'area di composizione",
   "keyboard_shortcuts.description": "Descrizione",
+  "keyboard_shortcuts.direct": "per aprire la colonna dei messaggi diretti",
   "keyboard_shortcuts.down": "per spostarsi in basso nella lista",
   "keyboard_shortcuts.enter": "per aprire lo status",
   "keyboard_shortcuts.favourite": "per segnare come apprezzato",
+  "keyboard_shortcuts.favourites": "per aprire l'elenco dei toot apprezzati",
+  "keyboard_shortcuts.federated": "per aprire la timeline federata",
   "keyboard_shortcuts.heading": "Tasti di scelta rapida",
+  "keyboard_shortcuts.home": "per aprire la timeline home",
   "keyboard_shortcuts.hotkey": "Tasto di scelta rapida",
   "keyboard_shortcuts.legend": "per mostrare questa spiegazione",
+  "keyboard_shortcuts.local": "per aprire la timeline locale",
   "keyboard_shortcuts.mention": "per menzionare l'autore",
+  "keyboard_shortcuts.muted": "per aprire l'elenco degli utenti silenziati",
+  "keyboard_shortcuts.my_profile": "per aprire il tuo profilo",
+  "keyboard_shortcuts.notifications": "per aprire la colonna delle notifiche",
+  "keyboard_shortcuts.pinned": "per aprire l'elenco dei toot fissati in cima",
+  "keyboard_shortcuts.profile": "per aprire il profilo dell'autore",
   "keyboard_shortcuts.reply": "per rispondere",
+  "keyboard_shortcuts.requests": "per aprire l'elenco delle richieste di seguirti",
   "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.toot": "per iniziare a scrivere un toot completamente nuovo",
   "keyboard_shortcuts.unfocus": "per uscire dall'area di composizione o dalla ricerca",
@@ -154,19 +208,21 @@
   "lists.new.title_placeholder": "Titolo della nuova lista",
   "lists.search": "Cerca tra le persone che segui",
   "lists.subheading": "Le tue liste",
-  "loading_indicator.label": "Carico...",
+  "loading_indicator.label": "Caricamento...",
   "media_gallery.toggle_visible": "Imposta visibilità",
   "missing_indicator.label": "Non trovato",
   "missing_indicator.sublabel": "Risorsa non trovata",
   "mute_modal.hide_notifications": "Nascondere le notifiche da quest'utente?",
+  "navigation_bar.apps": "App per dispositivi mobili",
   "navigation_bar.blocks": "Utenti bloccati",
   "navigation_bar.community_timeline": "Timeline locale",
+  "navigation_bar.compose": "Componi nuovo toot",
   "navigation_bar.direct": "Messaggi diretti",
   "navigation_bar.discover": "Scopri",
   "navigation_bar.domain_blocks": "Domini nascosti",
   "navigation_bar.edit_profile": "Modifica profilo",
   "navigation_bar.favourites": "Apprezzati",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Parole silenziate",
   "navigation_bar.follow_requests": "Richieste di amicizia",
   "navigation_bar.info": "Informazioni estese",
   "navigation_bar.keyboard_shortcuts": "Tasti di scelta rapida",
@@ -186,36 +242,22 @@
   "notifications.clear_confirmation": "Vuoi davvero cancellare tutte le notifiche?",
   "notifications.column_settings.alert": "Notifiche desktop",
   "notifications.column_settings.favourite": "Apprezzati:",
+  "notifications.column_settings.filter_bar.advanced": "Mostra tutte le categorie",
+  "notifications.column_settings.filter_bar.category": "Filtro rapido",
+  "notifications.column_settings.filter_bar.show": "Mostra",
   "notifications.column_settings.follow": "Nuovi seguaci:",
   "notifications.column_settings.mention": "Menzioni:",
   "notifications.column_settings.push": "Notifiche push",
-  "notifications.column_settings.push_meta": "Questo dispositivo",
   "notifications.column_settings.reblog": "Post condivisi:",
   "notifications.column_settings.show": "Mostra in colonna",
   "notifications.column_settings.sound": "Riproduci suono",
+  "notifications.filter.all": "Tutti",
+  "notifications.filter.boosts": "Condivisioni",
+  "notifications.filter.favourites": "Apprezzati",
+  "notifications.filter.follows": "Seguaci",
+  "notifications.filter.mentions": "Menzioni",
   "notifications.group": "{count} notifiche",
-  "onboarding.done": "Fatto",
-  "onboarding.next": "Prossimo",
-  "onboarding.page_five.public_timelines": "La timeline locale mostra i post pubblici di tutti gli utenti di {domain}. La timeline federata mostra i post pubblici di tutti gli utenti seguiti da quelli di {domain}. Queste sono le timeline pubbliche, che vi danno grandi possibilità di scoprire nuovi utenti.",
-  "onboarding.page_four.home": "La timeline home mostra i post degli utenti che segui.",
-  "onboarding.page_four.notifications": "La colonna delle notifiche ti fa vedere quando qualcuno interagisce con te.",
-  "onboarding.page_one.federation": "Mastodon è una rete di server indipendenti che si collegano tra loro per formare un grande social network. I singoli server sono detti istanze.",
-  "onboarding.page_one.full_handle": "Il tuo nome utente completo",
-  "onboarding.page_one.handle_hint": "È ciò che diresti ai tuoi amici di cercare per trovarti.",
-  "onboarding.page_one.welcome": "Benvenuto in Mastodon!",
-  "onboarding.page_six.admin": "L'amministratore della tua istanza è {admin}.",
-  "onboarding.page_six.almost_done": "Quasi finito...",
-  "onboarding.page_six.appetoot": "Buon appetoot!",
-  "onboarding.page_six.apps_available": "Esistono {apps} per iOS, Android e altre piattaforme.",
-  "onboarding.page_six.github": "Mastodon è software libero e open-source. Puoi segnalare bug, richiedere nuove funzionalità, o contribuire al codice su {github}.",
-  "onboarding.page_six.guidelines": "linee guida per la comunità",
-  "onboarding.page_six.read_guidelines": "Ti preghiamo di leggere le {guidelines} di {domain}!",
-  "onboarding.page_six.various_app": "app per dispositivi mobili",
-  "onboarding.page_three.profile": "Puoi modificare il tuo profilo per cambiare i tuoi avatar, biografia e nome pubblico. E potrai trovarci altre preferenze.",
-  "onboarding.page_three.search": "Usa la barra di ricerca per trovare persone e hashtag, come {illustration} e {introductions}. Per trovare una persona che non è su questa istanza, usa il suo nome utente completo.",
-  "onboarding.page_two.compose": "Puoi scrivere dei post dalla colonna di composizione. Puoi caricare immagini, modificare le impostazioni di privacy, e aggiungere avvisi sul contenuto con le icone qui sotto.",
-  "onboarding.skip": "Salta",
-  "privacy.change": "Modifica privacy post",
+  "privacy.change": "Modifica privacy del post",
   "privacy.direct.long": "Invia solo a utenti menzionati",
   "privacy.direct.short": "Diretto",
   "privacy.private.long": "Invia solo ai seguaci",
@@ -234,7 +276,7 @@
   "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 sara' invata ai tuoi moderatori di istanza. Di seguito, puoi fornire  il motivo per il quale stai segnalando questo account:",
+  "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.placeholder": "Commenti aggiuntivi",
   "report.submit": "Invia",
   "report.target": "Invio la segnalazione {target}",
@@ -250,10 +292,13 @@
   "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.cancel_reblog_private": "Annulla condivisione",
   "status.cannot_reblog": "Questo post non può essere condiviso",
   "status.delete": "Elimina",
+  "status.detailed_status": "Vista conversazione dettagliata",
   "status.direct": "Messaggio diretto @{name}",
   "status.embed": "Incorpora",
   "status.favourite": "Apprezzato",
@@ -267,9 +312,11 @@
   "status.open": "Espandi questo post",
   "status.pin": "Fissa in cima sul profilo",
   "status.pinned": "Toot fissato in cima",
+  "status.read_more": "Leggi altro",
   "status.reblog": "Condividi",
   "status.reblog_private": "Condividi con i destinatari iniziali",
   "status.reblogged_by": "{name} ha condiviso",
+  "status.reblogs.empty": "Nessuno ha ancora condiviso questo toot. Quando qualcuno lo farà, comparirà qui.",
   "status.redraft": "Cancella e riscrivi",
   "status.reply": "Rispondi",
   "status.replyAll": "Rispondi alla conversazione",
@@ -281,28 +328,31 @@
   "status.show_less_all": "Mostra meno per tutti",
   "status.show_more": "Mostra di più",
   "status.show_more_all": "Mostra di più per tutti",
+  "status.show_thread": "Mostra thread",
   "status.unmute_conversation": "Annulla silenzia conversazione",
   "status.unpin": "Non fissare in cima al profilo",
+  "suggestions.dismiss": "Elimina suggerimento",
+  "suggestions.header": "Ti potrebbe interessare…",
   "tabs_bar.federated_timeline": "Federazione",
   "tabs_bar.home": "Home",
   "tabs_bar.local_timeline": "Locale",
   "tabs_bar.notifications": "Notifiche",
   "tabs_bar.search": "Cerca",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "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_form.description": "Descrizione per utenti con disabilità visive",
-  "upload_form.focus": "Rifila",
+  "upload_form.focus": "Modifica anteprima",
   "upload_form.undo": "Cancella",
   "upload_progress.label": "Sto caricando...",
   "video.close": "Chiudi video",
   "video.exit_fullscreen": "Esci da modalità a schermo intero",
   "video.expand": "Espandi video",
-  "video.fullscreen": "Full screen",
+  "video.fullscreen": "Schermo intero",
   "video.hide": "Nascondi video",
   "video.mute": "Silenzia suono",
-  "video.pause": "Pause",
+  "video.pause": "Pausa",
   "video.play": "Avvia",
   "video.unmute": "Riattiva suono"
 }
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index c742b883e908334d802a54c95751b7ac9f84fecf..cd4addd68679c00e5e5ca4c5653697ff9dd8d082 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "リストに追加または外す",
   "account.badges.bot": "Bot",
   "account.block": "@{name}さんをブロック",
   "account.block_domain": "{domain}全体を非表示",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "以下の情報は不正確な可能性があります。",
   "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}さんは引っ越しました:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "@{name}さんからのブーストを表示",
   "account.unblock": "@{name}さんのブロックを解除",
   "account.unblock_domain": "{domain}を表示",
+  "account.unendorse": "プロフィールから外す",
   "account.unfollow": "フォロー解除",
   "account.unmute": "@{name}さんのミュートを解除",
   "account.unmute_notifications": "@{name}さんからの通知を受け取るようにする",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "ミュート",
   "confirmations.mute.message": "本当に{name}さんをミュートしますか?",
   "confirmations.redraft.confirm": "削除して下書きに戻す",
-  "confirmations.redraft.message": "本当にこのトゥートを削除して下書きに戻しますか? このトゥートへの全ての返信やブースト、お気に入り登録を失うことになります。",
+  "confirmations.redraft.message": "本当にこのトゥートを削除して下書きに戻しますか? このトゥートへのお気に入り登録やブーストは失われ、返信は孤立することになります。",
+  "confirmations.reply.confirm": "返信",
+  "confirmations.reply.message": "今返信すると現在作成中のメッセージが上書きされます。本当に実行しますか?",
   "confirmations.unfollow.confirm": "フォロー解除",
   "confirmations.unfollow.message": "本当に{name}さんのフォローを解除しますか?",
   "embed.instructions": "下記のコードをコピーしてウェブサイトに埋め込みます。",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "検索結果",
   "emoji_button.symbols": "記号",
   "emoji_button.travel": "旅行と場所",
+  "empty_column.account_timeline": "トゥートがありません!",
+  "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.find_friends": "Twitterの友達を探す",
   "getting_started.heading": "スタート",
   "getting_started.invite": "招待",
-  "getting_started.open_source_notice": "Mastodonはオープンソースソフトウェアです。誰でもGitHub({github})から開発に参加したり、問題を報告したりできます。",
+  "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.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": "次へ",
+  "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": "お気に入り登録することで後から見られるよう保存したり、「好き」を相手に伝えたりできます。",
+  "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": "Fediverseの世界へようこそ!あと少しでメッセージを配信したり、さまざまなサーバーを越えた友達と話せるようになります。ところでここ{domain}は特別なサーバーです…あなたのプロフィールを持つ主体のサーバーですので、名前を覚えておきましょう。",
   "keyboard_shortcuts.back": "戻る",
+  "keyboard_shortcuts.blocked": "ブロックしたユーザーのリストを開く",
   "keyboard_shortcuts.boost": "ブースト",
   "keyboard_shortcuts.column": "左からn番目のカラム内最新トゥートに移動",
   "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.toot": "新規トゥート",
   "keyboard_shortcuts.unfocus": "トゥート入力欄・検索欄から離れる",
@@ -159,14 +213,16 @@
   "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": "Muted words",
+  "navigation_bar.filters": "フィルター設定",
   "navigation_bar.follow_requests": "フォローリクエスト",
   "navigation_bar.info": "このインスタンスについて",
   "navigation_bar.keyboard_shortcuts": "ホットキー",
@@ -186,36 +242,22 @@
   "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.push": "プッシュ通知",
-  "notifications.column_settings.push_meta": "このデバイス",
   "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.group": "{count} 件の通知",
-  "onboarding.done": "完了",
-  "onboarding.next": "次へ",
-  "onboarding.page_five.public_timelines": "連合タイムラインでは{domain}の人がフォローしているMastodon全体での公開投稿を表示します。同じくローカルタイムラインでは{domain}のみの公開投稿を表示します。",
-  "onboarding.page_four.home": "「ホーム」タイムラインではあなたがフォローしている人の投稿を表示します。",
-  "onboarding.page_four.notifications": "「通知」ではあなたへの他の人からの関わりを表示します。",
-  "onboarding.page_one.federation": "Mastodonは独立したインスタンス(サーバー)の集合体です。",
-  "onboarding.page_one.full_handle": "あなたのフルハンドル",
-  "onboarding.page_one.handle_hint": "あなたを探している友達に伝えるといいでしょう。",
-  "onboarding.page_one.welcome": "Mastodonへようこそ!",
-  "onboarding.page_six.admin": "あなたのインスタンスの管理者は{admin}です。",
-  "onboarding.page_six.almost_done": "以上です。",
-  "onboarding.page_six.appetoot": "ボナペトゥート!",
-  "onboarding.page_six.apps_available": "iOS、Androidあるいは他のプラットフォームで使える{apps}があります。",
-  "onboarding.page_six.github": "MastodonはOSSです。バグ報告や機能要望あるいは貢献を{github}から行なえます。",
-  "onboarding.page_six.guidelines": "コミュニティガイドライン",
-  "onboarding.page_six.read_guidelines": "{domain}の{guidelines}を読むことを忘れないようにしてください!",
-  "onboarding.page_six.various_app": "モバイルアプリ",
-  "onboarding.page_three.profile": "「プロフィールを編集」から、あなたの自己紹介や表示名を変更できます。またそこでは他の設定ができます。",
-  "onboarding.page_three.search": "検索バーで、{illustration}や{introductions}のように特定のハッシュタグの投稿を見たり、ユーザーを探したりできます。",
-  "onboarding.page_two.compose": "フォームから投稿できます。イメージや、公開範囲の設定や、表示時の警告の設定は下部のアイコンから行えます。",
-  "onboarding.skip": "スキップ",
-  "privacy.change": "投稿のプライバシーを変更",
+  "privacy.change": "公開範囲を変更",
   "privacy.direct.long": "メンションしたユーザーだけに公開",
   "privacy.direct.short": "ダイレクト",
   "privacy.private.long": "フォロワーだけに公開",
@@ -250,10 +292,13 @@
   "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.delete": "削除",
+  "status.detailed_status": "詳細な会話ビュー",
   "status.direct": "@{name}さんにダイレクトメッセージ",
   "status.embed": "埋め込み",
   "status.favourite": "お気に入り",
@@ -267,9 +312,11 @@
   "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": "全員に返信",
@@ -281,8 +328,11 @@
   "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": "ローカル",
@@ -291,7 +341,7 @@
   "trends.count_by_accounts": "{count} {rawCount, plural, one {人} other {人}} がトゥート",
   "ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。",
   "upload_area.title": "ドラッグ&ドロップでアップロード",
-  "upload_button.label": "メディアを追加",
+  "upload_button.label": "メディアを追加 (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "視覚障害者のための説明",
   "upload_form.focus": "焦点",
   "upload_form.undo": "削除",
diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json
new file mode 100644
index 0000000000000000000000000000000000000000..93a11027a689db304c5f90c218e178fab8a9c5ad
--- /dev/null
+++ b/app/javascript/mastodon/locales/ka.json
@@ -0,0 +1,358 @@
+{
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "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.follow": "გაყოლა",
+  "account.followers": "მიმდევრები",
+  "account.followers.empty": "No one follows this user yet.",
+  "account.follows": "მიდევნებები",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "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.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}-სგან",
+  "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.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.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": "თქვენი გაფრთხილება დაწერეთ აქ",
+  "confirmation_modal.cancel": "უარყოფა",
+  "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": "Reply",
+  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "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": "No toots here!",
+  "empty_column.blocks": "You haven't blocked any users yet.",
+  "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.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.notifications": "ჯერ შეტყობინებები არ გაქვთ. საუბრის დასაწყებად იურთიერთქმედეთ სხვებთან.",
+  "empty_column.public": "აქ არაფერია! შესავსებად, დაწერეთ რაიმე ღიად ან ხელით გაჰყევით მომხმარებლებს სხვა ინსტანციებისგან",
+  "follow_request.authorize": "ავტორიზაცია",
+  "follow_request.reject": "უარყოფა",
+  "getting_started.developers": "დეველოპერები",
+  "getting_started.directory": "Profile 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",
+  "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": "to open blocked users list",
+  "keyboard_shortcuts.boost": "დასაბუსტად",
+  "keyboard_shortcuts.column": "ერთ-ერთი სვეტში სტატუსზე ფოკუსირებისთვის",
+  "keyboard_shortcuts.compose": "შედგენის ტექსტ-არეაზე ფოკუსირებისთვის",
+  "keyboard_shortcuts.description": "აღწერილობა",
+  "keyboard_shortcuts.direct": "to open direct messages column",
+  "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.heading": "კლავიატურის სწრაფი ბმულები",
+  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.hotkey": "ცხელი კლავიში",
+  "keyboard_shortcuts.legend": "ამ ლეგენდის გამოსაჩენად",
+  "keyboard_shortcuts.local": "to open local timeline",
+  "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": "ავტორის პროფილის გასახსნელად",
+  "keyboard_shortcuts.reply": "პასუხისთვის",
+  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.search": "ძიებაზე ფოკუსირებისთვის",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.toggle_hidden": "გაფრთხილების უკან ტექსტის გამოსაჩენად/დასამალვად",
+  "keyboard_shortcuts.toot": "ახალი ტუტის დასაწყებად",
+  "keyboard_shortcuts.unfocus": "შედგენის ტექსტ-არეაზე ფოკუსის მოსაშორებლად",
+  "keyboard_shortcuts.up": "სიაში ზემოთ გადასაადგილებლად",
+  "lightbox.close": "დახურვა",
+  "lightbox.next": "შემდეგი",
+  "lightbox.previous": "წინა",
+  "lists.account.add": "სიაში დამატება",
+  "lists.account.remove": "სიიდან ამოშლა",
+  "lists.delete": "სიის წაშლა",
+  "lists.edit": "სიის შეცვლა",
+  "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": "Mobile apps",
+  "navigation_bar.blocks": "დაბლოკილი მომხმარებლები",
+  "navigation_bar.community_timeline": "ლოკალური თაიმლაინი",
+  "navigation_bar.compose": "Compose new 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.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.public_timeline": "ფედერალური თაიმლაინი",
+  "navigation_bar.security": "უსაფრთხოება",
+  "notification.favourite": "{name}-მა თქვენი სტატუსი აქცია ფავორიტად",
+  "notification.follow": "{name} გამოგყვათ",
+  "notification.mention": "{name}-მა გასახელათ",
+  "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.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.group": "{count} შეტყობინება",
+  "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": "შიდა ხედი...",
+  "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.delete": "წაშლა",
+  "status.detailed_status": "Detailed conversation view",
+  "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": "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.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.unmute_conversation": "საუბარზე გაჩუმების მოშორება",
+  "status.unpin": "პროფილიდან პინის მოშორება",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
+  "tabs_bar.federated_timeline": "ფედერალური",
+  "tabs_bar.home": "სახლი",
+  "tabs_bar.local_timeline": "ლოკალური",
+  "tabs_bar.notifications": "შეტყობინებები",
+  "tabs_bar.search": "ძებნა",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} საუბრობს",
+  "ui.beforeunload": "თქვენი დრაფტი გაუქმდება თუ დატოვებთ მასტოდონს.",
+  "upload_area.title": "გადმოწიეთ და ჩააგდეთ ასატვირთათ",
+  "upload_button.label": "მედიის დამატება",
+  "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 8f4b57c2b6a99816096ee35f06792b4787f54957..ceb474a3e54974dd3941f0a912523b33f0d52c7d 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "리스트에 추가 혹은 삭제",
   "account.badges.bot": "ë´‡",
   "account.block": "@{name}을 차단",
   "account.block_domain": "{domain} 전체를 숨김",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "여기 있는 정보는 유저의 프로파일을 정확히 반영하지 못 할 수도 있습니다.",
   "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}는 계정을 이동했습니다:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "@{name}의 부스트 보기",
   "account.unblock": "차단 해제",
   "account.unblock_domain": "{domain} 숨김 해제",
+  "account.unendorse": "프로필에 나타내지 않기",
   "account.unfollow": "팔로우 해제",
   "account.unmute": "뮤트 해제",
   "account.unmute_notifications": "@{name}의 알림 뮤트 해제",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "뮤트",
   "confirmations.mute.message": "정말로 {name}를 뮤트하시겠습니까?",
   "confirmations.redraft.confirm": "삭제하고 다시 쓰기",
-  "confirmations.redraft.message": "정말로 이 포스트를 삭제하고 다시 쓰시겠습니까? 해당 포스트에 대한 답장과 부스트, 그리고 즐겨찾기를 잃게 됩니다.",
+  "confirmations.redraft.message": "정말로 이 포스트를 삭제하고 다시 쓰시겠습니까? 해당 포스트에 대한 부스트와 즐겨찾기를 잃게 되고 원본에 대한 답장은 연결 되지 않습니다.",
+  "confirmations.reply.confirm": "답글",
+  "confirmations.reply.message": "답글을 달기 위해 현재 작성 중인 메시지가 덮어 씌워집니다. 진행하시겠습니까?",
   "confirmations.unfollow.confirm": "언팔로우",
   "confirmations.unfollow.message": "정말로 {name}를 언팔로우하시겠습니까?",
   "embed.instructions": "아래의 코드를 복사하여 대화를 원하는 곳으로 공유하세요.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "검색 결과",
   "emoji_button.symbols": "기호",
   "emoji_button.travel": "여행과 장소",
+  "empty_column.account_timeline": "여긴 툿이 없어요!",
+  "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.find_friends": "트위터에서 친구 찾기",
   "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.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",
   "home.column_settings.basic": "기본 설정",
   "home.column_settings.show_reblogs": "부스트 표시",
   "home.column_settings.show_replies": "답글 표시",
+  "introduction.federation.action": "다음",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "페디버스의 다른 서버의 공개 게시물이 연합 타임라인에 나타납니다.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "당신이 팔로우 하고 있는 사람의 게시물이 홈 타임라인에 나타납니다. 어느 서버에 있는 사람이라도 팔로우가 가능합니다!",
+  "introduction.federation.local.headline": "Local",
+  "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.toot": "새 툿 작성",
   "keyboard_shortcuts.unfocus": "작성창에서 포커스 해제",
@@ -159,14 +213,16 @@
   "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": "Muted words",
+  "navigation_bar.filters": "뮤트",
   "navigation_bar.follow_requests": "팔로우 요청",
   "navigation_bar.info": "이 인스턴스에 대해서",
   "navigation_bar.keyboard_shortcuts": "단축키",
@@ -186,35 +242,21 @@
   "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.push": "푸시 알림",
-  "notifications.column_settings.push_meta": "이 장치",
   "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.group": "{count} 개의 알림",
-  "onboarding.done": "완료",
-  "onboarding.next": "다음",
-  "onboarding.page_five.public_timelines": "연합 타임라인에서는 {domain}의 사람들이 팔로우 중인 Mastodon 전체 인스턴스의 공개 포스트를 표시합니다. 로컬 타임라인에서는 {domain} 만의 공개 포스트를 표시합니다.",
-  "onboarding.page_four.home": "홈 타임라인에서는 내가 팔로우 중인 사람들의 포스트를 표시합니다.",
-  "onboarding.page_four.notifications": "알림에서는 다른 사람들과의 연결을 표시합니다.",
-  "onboarding.page_one.federation": "마스토돈은 누구나 참가할 수 있는 SNS입니다.",
-  "onboarding.page_one.full_handle": "당신의 풀 핸들",
-  "onboarding.page_one.handle_hint": "이것을 검색하여 친구들이 당신을 찾을 수 있습니다.",
-  "onboarding.page_one.welcome": "마스토돈에 어서 오세요!",
-  "onboarding.page_six.admin": "이 인스턴스의 관리자는 {admin}입니다.",
-  "onboarding.page_six.almost_done": "이상입니다.",
-  "onboarding.page_six.appetoot": "본 아페툿!",
-  "onboarding.page_six.apps_available": "iOS、Android 또는 다른 플랫폼에서 사용할 수 있는 {apps}이 있습니다.",
-  "onboarding.page_six.github": "마스토돈은 오픈 소스 소프트웨어입니다. 버그 보고나 기능 추가 요청, 기여는 {github}에서 할 수 있습니다.",
-  "onboarding.page_six.guidelines": "커뮤니티 가이드라인",
-  "onboarding.page_six.read_guidelines": "{domain}의 {guidelines}을 확인하는 것을 잊지 마세요!",
-  "onboarding.page_six.various_app": "다양한 모바일 애플리케이션",
-  "onboarding.page_three.profile": "[프로필 편집] 에서 자기 소개나 이름을 변경할 수 있습니다. 또한 다른 설정도 변경할 수 있습니다.",
-  "onboarding.page_three.search": "검색 바에서 {illustration} 나 {introductions} 와 같이 특정 해시태그가 달린 포스트를 보거나, 사용자를 찾을 수 있습니다.",
-  "onboarding.page_two.compose": "이 폼에서 포스팅 할 수 있습니다. 이미지나 공개 범위 설정, 스포일러 경고 설정은 아래 아이콘으로 설정할 수 있습니다.",
-  "onboarding.skip": "건너뛰기",
   "privacy.change": "포스트의 프라이버시 설정을 변경",
   "privacy.direct.long": "멘션한 사용자에게만 공개",
   "privacy.direct.short": "다이렉트",
@@ -250,10 +292,13 @@
   "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.delete": "삭제",
+  "status.detailed_status": "대화 자세히 보기",
   "status.direct": "@{name}에게 다이렉트 메시지",
   "status.embed": "공유하기",
   "status.favourite": "즐겨찾기",
@@ -267,9 +312,11 @@
   "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": "전원에게 답장",
@@ -281,8 +328,11 @@
   "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": "로컬",
@@ -291,9 +341,9 @@
   "trends.count_by_accounts": "{count} {rawCount, plural, one {명} other {명}} 의 사람들이 말하고 있습니다",
   "ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.",
   "upload_area.title": "드래그 & 드롭으로 업로드",
-  "upload_button.label": "미디어 추가",
+  "upload_button.label": "미디어 추가 (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "시각장애인을 위한 설명",
-  "upload_form.focus": "크롭",
+  "upload_form.focus": "미리보기 변경",
   "upload_form.undo": "삭제",
   "upload_progress.label": "업로드 중...",
   "video.close": "동영상 닫기",
diff --git a/app/javascript/mastodon/locales/locale-data/co.js b/app/javascript/mastodon/locales/locale-data/co.js
new file mode 100644
index 0000000000000000000000000000000000000000..2b071ecbd450ba67a5da952296883b8ab593e1df
--- /dev/null
+++ b/app/javascript/mastodon/locales/locale-data/co.js
@@ -0,0 +1,108 @@
+/*eslint eqeqeq: "off"*/
+/*eslint no-nested-ternary: "off"*/
+/*eslint quotes: "off"*/
+
+export default [{
+  locale: "co",
+  pluralRuleFunction: function (e, a) {
+    return a ? 1 == e ? "one" : "other" : e >= 0 && e < 2 ? "one" : "other";
+  },
+  fields: {
+    year: {
+      displayName: "annu",
+      relative: {
+        0: "quist'annu",
+        1: "l'annu chì vene",
+        "-1": "l'annu passatu",
+      },
+      relativeTime: {
+        future: {
+          one: "in {0} annu",
+          other: "in {0} anni",
+        },
+        past: {
+          one: "{0} annu fà",
+          other: "{0} anni fà",
+        },
+      },
+    },
+    month: {
+      displayName: "mese",
+      relative: {
+        0: "Questu mese",
+        1: "u mese chì vene",
+        "-1": "u mese passatu",
+      },
+      relativeTime: {
+        future: {
+          one: "in {0} mese",
+          other: "in {0} mesi",
+        },
+        past: {
+          one: "{0} mese fà",
+          other: "{0} mesi fà",
+        },
+      },
+    },
+    day: {
+      displayName: "ghjornu",
+      relative: {
+        0: "oghje",
+        1: "dumane",
+        "-1": "eri",
+      },
+      relativeTime: {
+        future: {
+          one: "in {0} ghjornu",
+          other: "in {0} ghjornu",
+        },
+        past: {
+          one: "{0} ghjornu fà",
+          other: "{0} ghjorni fà",
+        },
+      },
+    },
+    hour: {
+      displayName: "ora",
+      relativeTime: {
+        future: {
+          one: "in {0} ora",
+          other: "in {0} ore",
+        },
+        past: {
+          one: "{0} ora fà",
+          other: "{0} ore fà",
+        },
+      },
+    },
+    minute: {
+      displayName: "minuta",
+      relativeTime: {
+        future: {
+          one: "in {0} minuta",
+          other: "in {0} minute",
+        },
+        past: {
+          one: "{0} minuta fà",
+          other: "{0} minute fà",
+        },
+      },
+    },
+    second: {
+      displayName: "siconda",
+      relative: {
+        0: "avà",
+      },
+      relativeTime: {
+        future: {
+          one: "in {0} siconda",
+          other: "in {0} siconde",
+        },
+        past: {
+          one: "{0} siconda fà",
+          other: "{0} siconde fà",
+        },
+      },
+    },
+  },
+}];
diff --git a/app/javascript/mastodon/locales/locale-data/oc.js b/app/javascript/mastodon/locales/locale-data/oc.js
index c4b56350b72d264da7741dfbd5d66b7b751b0bd1..d4adc42ebb6b018251ac5393ec813ee960c587f1 100644
--- a/app/javascript/mastodon/locales/locale-data/oc.js
+++ b/app/javascript/mastodon/locales/locale-data/oc.js
@@ -17,8 +17,8 @@ export default [{
       },
       relativeTime: {
         future: {
-          one: "dins {0} an",
-          other: "dins {0} ans",
+          one: "d’aquí {0} an",
+          other: "d’aquí {0} ans",
         },
         past: {
           one: "fa {0} an",
@@ -35,8 +35,8 @@ export default [{
       },
       relativeTime: {
         future: {
-          one: "dins {0} mes",
-          other: "dins {0} meses",
+          one: "d’aquí {0} mes",
+          other: "d’aquí {0} meses",
         },
         past: {
           one: "fa {0} mes",
@@ -53,8 +53,8 @@ export default [{
       },
       relativeTime: {
         future: {
-          one: "dins {0} jorn",
-          other: "dins {0} jorns",
+          one: "d’aquí {0} jorn",
+          other: "d’aquí {0} jorns",
         },
         past: {
           one: "fa {0} jorn",
@@ -66,8 +66,8 @@ export default [{
       displayName: "ora",
       relativeTime: {
         future: {
-          one: "dins {0} ora",
-          other: "dins {0} oras",
+          one: "d’aquí {0} ora",
+          other: "d’aquí {0} oras",
         },
         past: {
           one: "fa {0} ora",
@@ -79,8 +79,8 @@ export default [{
       displayName: "minuta",
       relativeTime: {
         future: {
-          one: "dins {0} minuta",
-          other: "dins {0} minutas",
+          one: "d’aquí {0} minuta",
+          other: "d’aquí {0} minutas",
         },
         past: {
           one: "fa {0} minuta",
@@ -95,8 +95,8 @@ export default [{
       },
       relativeTime: {
         future: {
-          one: "dins {0} segonda",
-          other: "dins {0} segondas",
+          one: "d’aquí {0} segonda",
+          other: "d’aquí {0} segondas",
         },
         past: {
           one: "fa {0} segonda",
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d510d011fd988fa03addb3c713686883efb4131
--- /dev/null
+++ b/app/javascript/mastodon/locales/lv.json
@@ -0,0 +1,358 @@
+{
+  "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",
+  "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",
+  "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",
+  "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.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": "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.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!",
+  "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": "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}}",
+  "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",
+  "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",
+  "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/ms.json b/app/javascript/mastodon/locales/ms.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d510d011fd988fa03addb3c713686883efb4131
--- /dev/null
+++ b/app/javascript/mastodon/locales/ms.json
@@ -0,0 +1,358 @@
+{
+  "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",
+  "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",
+  "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",
+  "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.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": "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.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!",
+  "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": "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}}",
+  "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",
+  "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",
+  "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/nl.json b/app/javascript/mastodon/locales/nl.json
index 63c902668a6aebbbe8c40ad3f9d2e8f33f0a7287..871142195df56ca878bacca7c153c7080ed1663a 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -1,17 +1,23 @@
 {
+  "account.add_or_remove_from_list": "Toevoegen of verwijderen vanuit lijsten",
   "account.badges.bot": "Bot",
   "account.block": "Blokkeer @{name}",
-  "account.block_domain": "Negeer alles van {domain}",
+  "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.empty": "Deze gebruiker volgt nog niemand.",
   "account.follows_you": "Volgt jou",
   "account.hide_reblogs": "Verberg boosts van @{name}",
+  "account.link_verified_on": "Eigendom van deze link is gecontroleerd op {date}",
+  "account.locked_info": "De privacystatus van dit account is op besloten gezet. De eigenaar bepaalt handmatig wie hen kan volgen.",
   "account.media": "Media",
   "account.mention": "Vermeld @{name}",
   "account.moved_to": "{name} is verhuisd naar:",
@@ -25,7 +31,8 @@
   "account.share": "Profiel van @{name} delen",
   "account.show_reblogs": "Toon boosts van @{name}",
   "account.unblock": "Deblokkeer @{name}",
-  "account.unblock_domain": "{domain} niet langer negeren",
+  "account.unblock_domain": "{domain} niet langer verbergen",
+  "account.unendorse": "Niet op profiel weergeven",
   "account.unfollow": "Ontvolgen",
   "account.unmute": "@{name} niet langer negeren",
   "account.unmute_notifications": "@{name} meldingen niet langer negeren",
@@ -42,7 +49,7 @@
   "column.blocks": "Geblokkeerde gebruikers",
   "column.community": "Lokale tijdlijn",
   "column.direct": "Directe berichten",
-  "column.domain_blocks": "Verborgen domeinen",
+  "column.domain_blocks": "Genegeerde servers",
   "column.favourites": "Favorieten",
   "column.follow_requests": "Volgverzoeken",
   "column.home": "Start",
@@ -80,12 +87,14 @@
   "confirmations.delete.message": "Weet je het zeker dat je deze toot wilt verwijderen?",
   "confirmations.delete_list.confirm": "Verwijderen",
   "confirmations.delete_list.message": "Weet je zeker dat je deze lijst definitief wilt verwijderen?",
-  "confirmations.domain_block.confirm": "Negeer alles van deze server",
+  "confirmations.domain_block.confirm": "Verberg alles van deze server",
   "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je zult geen toots van deze server op openbare tijdlijnen zien of in jouw meldingen. Jouw volgers van deze server worden verwijderd.",
   "confirmations.mute.confirm": "Negeren",
   "confirmations.mute.message": "Weet je het zeker dat je {name} wilt negeren?",
   "confirmations.redraft.confirm": "Verwijderen en herschrijven",
-  "confirmations.redraft.message": "Weet je zeker dat je deze toot wilt verwijderen en herschrijven? Je verliest wel alle reacties, boosts en favorieten.",
+  "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.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.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Zoekresultaten",
   "emoji_button.symbols": "Symbolen",
   "emoji_button.travel": "Reizen en plekken",
+  "empty_column.account_timeline": "Hier zijn geen toots!",
+  "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.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.",
   "empty_column.hashtag": "Er is nog niks te vinden onder deze hashtag.",
   "empty_column.home": "Jij volgt nog niemand. Bezoek {public} of gebruik het zoekvenster om andere mensen te ontmoeten.",
   "empty_column.home.public_timeline": "de globale tijdlijn",
   "empty_column.list": "Er is nog niks in deze lijst. Wanneer lijstleden nieuwe toots publiceren, zijn deze hier te zien.",
+  "empty_column.lists": "Jij hebt nog enkele lijst. Wanneer je er eentje hebt aangemaakt, valt deze hier te zien.",
+  "empty_column.mutes": "Jij hebt nog geen gebruikers genegeerd.",
   "empty_column.notifications": "Je hebt nog geen meldingen. Begin met iemand een gesprek.",
   "empty_column.public": "Er is hier helemaal niks! Toot iets in het openbaar of volg mensen van andere servers om het te vullen",
   "follow_request.authorize": "Goedkeuren",
   "follow_request.reject": "Afkeuren",
   "getting_started.developers": "Ontwikkelaars",
+  "getting_started.directory": "Gebruikersgids",
   "getting_started.documentation": "Documentatie",
-  "getting_started.find_friends": "Vind vrienden van Twitter",
   "getting_started.heading": "Aan de slag",
   "getting_started.invite": "Mensen uitnodigen",
   "getting_started.open_source_notice": "Mastodon is vrije software. Je kunt bijdragen of problemen melden op GitHub via {github}.",
   "getting_started.security": "Beveiliging",
   "getting_started.terms": "Voorwaarden",
+  "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.tag_mode.all": "Allemaal",
+  "hashtag.column_settings.tag_mode.any": "Een van deze",
+  "hashtag.column_settings.tag_mode.none": "Geen van deze",
+  "hashtag.column_settings.tag_toggle": "Additionele tags aan deze kolom toevoegen",
   "home.column_settings.basic": "Algemeen",
   "home.column_settings.show_reblogs": "Boosts tonen",
   "home.column_settings.show_replies": "Reacties tonen",
+  "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.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.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.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.",
+  "introduction.welcome.action": "Laten we beginnen!",
+  "introduction.welcome.headline": "Eerste stappen",
+  "introduction.welcome.text": "Welkom in de fediverse! Binnen enkele ogenblikken kun jij berichten (toots) versturen en met vrienden op veel verschillende servers praten. Maar deze server, {domain}, is speciaal—het herbergt jouw profiel, onthou dus de naam.",
   "keyboard_shortcuts.back": "om terug te gaan",
+  "keyboard_shortcuts.blocked": "om de door jou geblokkeerde gebruikers te tonen",
   "keyboard_shortcuts.boost": "om te boosten",
   "keyboard_shortcuts.column": "om op een toot te focussen in één van de kolommen",
   "keyboard_shortcuts.compose": "om het tekstvak voor toots te focussen",
   "keyboard_shortcuts.description": "Omschrijving",
+  "keyboard_shortcuts.direct": "om jouw directe berichten te tonen",
   "keyboard_shortcuts.down": "om naar beneden door de lijst te bewegen",
   "keyboard_shortcuts.enter": "om toot volledig te tonen",
-  "keyboard_shortcuts.favourite": "om als favoriet te markeren",
+  "keyboard_shortcuts.favourite": "om aan jouw favorieten toe te voegen",
+  "keyboard_shortcuts.favourites": "om jouw lijst met favorieten te tonen",
+  "keyboard_shortcuts.federated": "om de globale tijdlijn te tonen",
   "keyboard_shortcuts.heading": "Sneltoetsen",
+  "keyboard_shortcuts.home": "om jouw starttijdlijn te tonen",
   "keyboard_shortcuts.hotkey": "Sneltoets",
   "keyboard_shortcuts.legend": "om deze legenda te tonen",
+  "keyboard_shortcuts.local": "om de lokale tijdlijn te tonen",
   "keyboard_shortcuts.mention": "om de auteur te vermelden",
+  "keyboard_shortcuts.muted": "om de door jou genegeerde gebruikers te tonen",
+  "keyboard_shortcuts.my_profile": "om jouw profiel te tonen",
+  "keyboard_shortcuts.notifications": "om jouw meldingen te tonen",
+  "keyboard_shortcuts.pinned": "om jouw vastgezette toots te tonen",
+  "keyboard_shortcuts.profile": "om het gebruikersprofiel te openen",
   "keyboard_shortcuts.reply": "om te reageren",
+  "keyboard_shortcuts.requests": "om jouw volgverzoeken te tonen",
   "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.toot": "om een nieuwe toot te starten",
   "keyboard_shortcuts.unfocus": "om het tekst- en zoekvak te ontfocussen",
@@ -159,26 +213,28 @@
   "missing_indicator.label": "Niet gevonden",
   "missing_indicator.sublabel": "Deze hulpbron kan niet gevonden worden",
   "mute_modal.hide_notifications": "Verberg meldingen van deze persoon?",
+  "navigation_bar.apps": "Mobiele apps",
   "navigation_bar.blocks": "Geblokkeerde gebruikers",
   "navigation_bar.community_timeline": "Lokale tijdlijn",
+  "navigation_bar.compose": "Nieuw toot schrijven",
   "navigation_bar.direct": "Directe berichten",
   "navigation_bar.discover": "Ontdekken",
-  "navigation_bar.domain_blocks": "Verborgen domeinen",
+  "navigation_bar.domain_blocks": "Genegeerde domeinen",
   "navigation_bar.edit_profile": "Profiel bewerken",
   "navigation_bar.favourites": "Favorieten",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Filters",
   "navigation_bar.follow_requests": "Volgverzoeken",
   "navigation_bar.info": "Over deze server",
   "navigation_bar.keyboard_shortcuts": "Sneltoetsen",
   "navigation_bar.lists": "Lijsten",
-  "navigation_bar.logout": "Afmelden",
+  "navigation_bar.logout": "Uitloggen",
   "navigation_bar.mutes": "Genegeerde gebruikers",
   "navigation_bar.personal": "Persoonlijk",
   "navigation_bar.pins": "Vastgezette toots",
   "navigation_bar.preferences": "Instellingen",
   "navigation_bar.public_timeline": "Globale tijdlijn",
   "navigation_bar.security": "Beveiliging",
-  "notification.favourite": "{name} markeerde jouw toot als favoriet",
+  "notification.favourite": "{name} voegde jouw toot als favoriet toe",
   "notification.follow": "{name} volgt jou nu",
   "notification.mention": "{name} vermeldde jou",
   "notification.reblog": "{name} boostte jouw toot",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Weet je het zeker dat je al jouw meldingen wilt verwijderen?",
   "notifications.column_settings.alert": "Desktopmeldingen",
   "notifications.column_settings.favourite": "Favorieten:",
+  "notifications.column_settings.filter_bar.advanced": "Alle categorieën tonen",
+  "notifications.column_settings.filter_bar.category": "Snelle filterbalk",
+  "notifications.column_settings.filter_bar.show": "Tonen",
   "notifications.column_settings.follow": "Nieuwe volgers:",
   "notifications.column_settings.mention": "Vermeldingen:",
   "notifications.column_settings.push": "Pushmeldingen",
-  "notifications.column_settings.push_meta": "Dit apparaat",
   "notifications.column_settings.reblog": "Boosts:",
   "notifications.column_settings.show": "In kolom tonen",
   "notifications.column_settings.sound": "Geluid afspelen",
+  "notifications.filter.all": "Alles",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favorieten",
+  "notifications.filter.follows": "Die jij volgt",
+  "notifications.filter.mentions": "Vermeldingen",
   "notifications.group": "{count} meldingen",
-  "onboarding.done": "Klaar",
-  "onboarding.next": "Volgende",
-  "onboarding.page_five.public_timelines": "De lokale tijdlijn toont openbare toots van iedereen op {domain}. De globale tijdlijn toont openbare toots van iedereen die door gebruikers van {domain} worden gevolgd, dus ook mensen van andere Mastodonservers. Dit zijn de openbare tijdlijnen en vormen een uitstekende manier om nieuwe mensen te leren kennen.",
-  "onboarding.page_four.home": "Deze tijdlijn laat toots zien van mensen die jij volgt.",
-  "onboarding.page_four.notifications": "De kolom met meldingen toont alle interacties die je met andere Mastodongebruikers hebt.",
-  "onboarding.page_one.federation": "Mastodon is een netwerk van onafhankelijke servers die samen een groot sociaal netwerk vormen.",
-  "onboarding.page_one.full_handle": "Jouw volledige Mastodonadres",
-  "onboarding.page_one.handle_hint": "Dit is waarmee jouw vrienden je kunnen vinden.",
-  "onboarding.page_one.welcome": "Welkom op Mastodon!",
-  "onboarding.page_six.admin": "De beheerder van jouw Mastodonserver is {admin}.",
-  "onboarding.page_six.almost_done": "Bijna klaar...",
-  "onboarding.page_six.appetoot": "Veel succes!",
-  "onboarding.page_six.apps_available": "Er zijn {apps} beschikbaar voor iOS, Android en andere platformen.",
-  "onboarding.page_six.github": "Mastodon kost niets en is vrije software. Je kan bugs melden, nieuwe mogelijkheden aanvragen en als ontwikkelaar meewerken op {github}.",
-  "onboarding.page_six.guidelines": "communityrichtlijnen",
-  "onboarding.page_six.read_guidelines": "Vergeet niet de {guidelines} van {domain} te lezen!",
-  "onboarding.page_six.various_app": "mobiele apps",
-  "onboarding.page_three.profile": "Bewerk jouw profiel om jouw avatar, bio en weergavenaam te veranderen. Daar vind je ook andere instellingen.",
-  "onboarding.page_three.search": "Gebruik de zoekbalk linksboven om andere mensen op Mastodon te vinden en om te zoeken op hashtags, zoals {illustration} en {introductions}. Om iemand te vinden die niet op deze Mastodonserver zit, moet je het volledige Mastodonadres van deze persoon invoeren.",
-  "onboarding.page_two.compose": "Schrijf berichten (wij noemen dit toots) in het tekstvak in de linkerkolom. Je kan met de pictogrammen daaronder afbeeldingen uploaden, privacy-instellingen veranderen en je tekst een waarschuwing meegeven.",
-  "onboarding.skip": "Overslaan",
   "privacy.change": "Zichtbaarheid toot aanpassen",
   "privacy.direct.long": "Alleen aan vermelde gebruikers tonen",
   "privacy.direct.short": "Direct",
@@ -233,8 +275,8 @@
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Annuleren",
   "report.forward": "Doorsturen naar {target}",
-  "report.forward_hint": "Het account bevindt zich op een andere server. Stuur daar eveneens een geanonimiseerde kopie van de gerapporteerde toot(s) naartoe?",
-  "report.hint": "De gerapporteerde toot(s) worden naar de moderatoren van  jouw server gestuurd. Je kunt hieronder een uitleg geven waarom je dit account rapporteert:",
+  "report.forward_hint": "Het account bevindt zich op een andere server. Stuur daar eveneens een geanonimiseerde kopie van de rapportage naartoe?",
+  "report.hint": "De rapportage wordt naar de moderatoren van jouw server gestuurd. Je kunt hieronder een uitleg geven waarom je dit account rapporteert:",
   "report.placeholder": "Extra opmerkingen",
   "report.submit": "Verzenden",
   "report.target": "Rapporteer {target}",
@@ -250,10 +292,13 @@
   "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.delete": "Verwijderen",
+  "status.detailed_status": "Uitgebreide gespreksweergave",
   "status.direct": "Directe toot @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favoriet",
@@ -267,9 +312,11 @@
   "status.open": "Toot volledig tonen",
   "status.pin": "Aan profielpagina vastmaken",
   "status.pinned": "Vastgemaakte toot",
+  "status.read_more": "Meer lezen",
   "status.reblog": "Boost",
   "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.",
   "status.redraft": "Verwijderen en herschrijven",
   "status.reply": "Reageren",
   "status.replyAll": "Reageer op iedereen",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Alles minder tonen",
   "status.show_more": "Meer tonen",
   "status.show_more_all": "Alles meer tonen",
-  "status.unmute_conversation": "Conversatie niet langer negeren",
+  "status.show_thread": "Gesprek tonen",
+  "status.unmute_conversation": "Gesprek niet langer negeren",
   "status.unpin": "Van profielpagina losmaken",
+  "suggestions.dismiss": "Voorstel verwerpen",
+  "suggestions.header": "Je bent waarschijnlijk ook geïnteresseerd in…",
   "tabs_bar.federated_timeline": "Globaal",
   "tabs_bar.home": "Start",
   "tabs_bar.local_timeline": "Lokaal",
@@ -291,9 +341,9 @@
   "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",
+  "upload_button.label": "Media toevoegen (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking",
-  "upload_form.focus": "Bijsnijden",
+  "upload_form.focus": "Voorvertoning aanpassen",
   "upload_form.undo": "Verwijderen",
   "upload_progress.label": "Uploaden...",
   "video.close": "Video sluiten",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index 31bbf76642d09432088fcba7fcd7e430d53818ac..fa08e8d73b486da5f1ae4351367f40ec175b1277 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Blokkér @{name}",
   "account.block_domain": "Skjul alt fra {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Følg",
   "account.followers": "Følgere",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Følger",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Følger deg",
   "account.hide_reblogs": "Skjul fremhevinger fra @{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": "Nevn @{name}",
   "account.moved_to": "{name} har flyttet til:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Vis boosts fra @{name}",
   "account.unblock": "Avblokker @{name}",
   "account.unblock_domain": "Vis {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Avfølg",
   "account.unmute": "Avdemp @{name}",
   "account.unmute_notifications": "Vis varsler fra @{name}",
@@ -86,6 +93,8 @@
   "confirmations.mute.message": "Er du sikker på at du vil dempe {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": "Slutt å følge",
   "confirmations.unfollow.message": "Er du sikker på at du vil slutte å følge {name}?",
   "embed.instructions": "Kopier koden under for å bygge inn denne statusen på hjemmesiden din.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Søkeresultat",
   "emoji_button.symbols": "Symboler",
   "emoji_button.travel": "Reise & steder",
+  "empty_column.account_timeline": "No toots here!",
+  "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.",
+  "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": "Det er ingenting i denne hashtagen ennå.",
   "empty_column.home": "Du har ikke fulgt noen ennå. Besøk {publlic} eller bruk søk for å komme i gang og møte andre brukere.",
   "empty_column.home.public_timeline": "en offentlig tidslinje",
   "empty_column.list": "Det er ingenting i denne listen ennå. Når medlemmene av denne listen legger ut nye statuser vil de dukke opp her.",
+  "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": "Du har ingen varsler ennå. Kommuniser med andre for å begynne samtalen.",
   "empty_column.public": "Det er ingenting her! Skriv noe offentlig, eller følg brukere manuelt fra andre instanser for å fylle den opp",
   "follow_request.authorize": "Autorisér",
   "follow_request.reject": "Avvis",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Kom i gang",
   "getting_started.invite": "Invite people",
   "getting_started.open_source_notice": "Mastodon er fri programvare. Du kan bidra eller rapportere problemer på GitHub på {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": "Enkel",
   "home.column_settings.show_reblogs": "Vis fremhevinger",
   "home.column_settings.show_replies": "Vis svar",
+  "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": "for å navigere tilbake",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
   "keyboard_shortcuts.boost": "Ã¥ fremheve",
   "keyboard_shortcuts.column": "Ã¥ fokusere en status i en av kolonnene",
   "keyboard_shortcuts.compose": "Ã¥ fokusere komponeringsfeltet",
   "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "keyboard_shortcuts.down": "for å flytte ned i listen",
   "keyboard_shortcuts.enter": "to open status",
   "keyboard_shortcuts.favourite": "for å favorittmarkere",
+  "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": "Lyntast",
   "keyboard_shortcuts.legend": "Ã¥ vise denne forklaringen",
+  "keyboard_shortcuts.local": "to open local timeline",
   "keyboard_shortcuts.mention": "Ã¥ nevne forfatter",
+  "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": "for å svare",
+  "keyboard_shortcuts.requests": "to open follow requests list",
   "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.toot": "Ã¥ starte en helt ny tut",
   "keyboard_shortcuts.unfocus": "å ufokusere komponerings-/søkefeltet",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "Ikke funnet",
   "missing_indicator.sublabel": "Denne ressursen ble ikke funnet",
   "mute_modal.hide_notifications": "Skjul varslinger fra denne brukeren?",
+  "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokkerte brukere",
   "navigation_bar.community_timeline": "Lokal tidslinje",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Er du sikker på at du vil fjerne alle dine varsler permanent?",
   "notifications.column_settings.alert": "Skrivebordsvarslinger",
   "notifications.column_settings.favourite": "Likt:",
+  "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": "Nye følgere:",
   "notifications.column_settings.mention": "Nevnt:",
   "notifications.column_settings.push": "Push varsler",
-  "notifications.column_settings.push_meta": "Denne enheten",
   "notifications.column_settings.reblog": "Fremhevet:",
   "notifications.column_settings.show": "Vis i kolonne",
   "notifications.column_settings.sound": "Spill lyd",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifications",
-  "onboarding.done": "Ferdig",
-  "onboarding.next": "Neste",
-  "onboarding.page_five.public_timelines": "Den lokale tidslinjen viser offentlige poster fra alle på {domain}. Felles tidslinje viser offentlige poster fra alle som brukere på {domain} følger. Dette er de offentlige tidslinjene, et fint sted å oppdage nye brukere.",
-  "onboarding.page_four.home": "Hjem er tidslinjen med alle brukere som du følger.",
-  "onboarding.page_four.notifications": "Kolonnen med varsler viser når noen interakterer med deg.",
-  "onboarding.page_one.federation": "Mastdodon er et nettverk med uavhengige servere som sammarbeider om å danne et stort sosialt nettverk. Vi kaller disse serverene instanser.",
-  "onboarding.page_one.full_handle": "Ditt fulle kallenavn",
-  "onboarding.page_one.handle_hint": "Dette er hva du ber dine venner å søke etter.",
-  "onboarding.page_one.welcome": "Velkommen til Mastodon!",
-  "onboarding.page_six.admin": "Administratoren på din instans er {admin}.",
-  "onboarding.page_six.almost_done": "Snart ferdig...",
-  "onboarding.page_six.appetoot": "Bon Appetut!",
-  "onboarding.page_six.apps_available": "Det er {apps} tilgjengelig for iOS, Android og andre plattformer.",
-  "onboarding.page_six.github": "Mastodon er programvare med fri og åpen kildekode. Du kan rapportere feil, be om hjelp eller foreslå endringer på {github}.",
-  "onboarding.page_six.guidelines": "samfunnets retningslinjer",
-  "onboarding.page_six.read_guidelines": "Vennligst les {guidelines} for {domain}!",
-  "onboarding.page_six.various_app": "mobilapper",
-  "onboarding.page_three.profile": "Rediger profilen din for å endre din avatar, biografi, og visningsnavn. Der finner du også andre innstillinger.",
-  "onboarding.page_three.search": "Bruk søkemenyen for å søke etter emneknagger eller brukere, slik som {illustration} og {introductions}. For å søke på en bruker som ikke er på samme instans som deg bruk hele brukernavnet..",
-  "onboarding.page_two.compose": "Skriv innlegg fra forfatt-kolonnen. Du kan laste opp bilder, justere synlighet, og legge til innholdsvarsler med knappene under.",
-  "onboarding.skip": "Hopp over",
   "privacy.change": "Justér synlighet",
   "privacy.direct.long": "Post kun til nevnte brukere",
   "privacy.direct.short": "Direkte",
@@ -250,10 +292,13 @@
   "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.delete": "Slett",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Bygge inn",
   "status.favourite": "Lik",
@@ -267,9 +312,11 @@
   "status.open": "Utvid denne statusen",
   "status.pin": "Fest på profilen",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "Fremhev",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "Fremhevd av {name}",
+  "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": "Svar",
   "status.replyAll": "Svar til samtale",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Vis mer",
   "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Ikke demp samtale",
   "status.unpin": "Angre festing på profilen",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Felles",
   "tabs_bar.home": "Hjem",
   "tabs_bar.local_timeline": "Lokal",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index fb025594defc70247b56aeab493d339091d8ff23..c28e9f5b8344f3582f4821737e71ce84460b16ba 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Ajustar o tirar de las listas",
   "account.badges.bot": "Robòt",
   "account.block": "Blocar @{name}",
   "account.block_domain": "Tot amagar del domeni {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Sègre",
   "account.followers": "Seguidors",
+  "account.followers.empty": "Degun sèc pas aqueste utilizaire pel moment.",
   "account.follows": "Abonaments",
+  "account.follows.empty": "Aqueste utilizaire sèc pas degun pel moment.",
   "account.follows_you": "Vos sèc",
   "account.hide_reblogs": "Rescondre los partatges de @{name}",
+  "account.link_verified_on": "La proprietat d’aqueste ligam foguèt verificada lo {date}",
+  "account.locked_info": "L’estatut de privacitat del compte es configurat sus clavat. Lo proprietari causís qual pòt sègre son compte.",
   "account.media": "Mèdias",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} a mudat los catons a :",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Mostrar los partatges de @{name}",
   "account.unblock": "Desblocar @{name}",
   "account.unblock_domain": "Desblocar {domain}",
+  "account.unendorse": "Mostrar pas pel perfil",
   "account.unfollow": "Quitar de sègre",
   "account.unmute": "Quitar de rescondre @{name}",
   "account.unmute_notifications": "Mostrar las notificacions de @{name}",
@@ -62,7 +69,7 @@
   "community.column_settings.media_only": "Solament los mèdias",
   "compose_form.direct_message_warning": "Sols los mencionats poiràn veire aqueste tut.",
   "compose_form.direct_message_warning_learn_more": "Ne saber mai",
-  "compose_form.hashtag_warning": "Aqueste tut serà pas ligat a cap d’etiqueta estant qu’es pas listat. Òm pas cercar que los tuts publics per etiqueta.",
+  "compose_form.hashtag_warning": "Aqueste tut serà pas ligat a cap d’etiqueta estant qu’es pas listat. Òm pòt pas cercar que los tuts publics per etiqueta.",
   "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 ?",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "Rescondre",
   "confirmations.mute.message": "Volètz vertadièrament rescondre {name} ?",
   "confirmations.redraft.confirm": "Escafar & tornar formular",
-  "confirmations.redraft.message": "Volètz vertadièrament escafar aqueste estatut e lo reformular ? Perdretz totas sas responsas, sos partiments e favorits.",
+  "confirmations.redraft.message": "Volètz vertadièrament escafar aqueste estatut e lo reformular ? Totes sos partiments e favorits seràn perduts, e sas responsas seràn orfanèlas.",
+  "confirmations.reply.confirm": "Respondre",
+  "confirmations.reply.message": "Respondre remplaçarà lo messatge que sètz a escriure. Volètz vertadièrament contunhar ?",
   "confirmations.unfollow.confirm": "Quitar de sègre",
   "confirmations.unfollow.message": "Volètz vertadièrament quitar de sègre {name} ?",
   "embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Resultats de recèrca",
   "emoji_button.symbols": "Simbòls",
   "emoji_button.travel": "Viatges & lòcs",
+  "empty_column.account_timeline": "Cap de tuts aquí !",
+  "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í.",
+  "empty_column.domain_blocks": "I a pas encara cap de domeni amagat.",
+  "empty_column.favourited_statuses": "Avètz pas encara cap de tut favorit. Quand n’auretz un, apareisserà aquí.",
+  "empty_column.favourites": "Degun a pas encara mes en favorit aqueste tut. Quand qualqu’un o farà, apareisserà aquí.",
+  "empty_column.follow_requests": "Avètz pas encara de demanda d’abonament. Quand n’auretz una apareisserà aquí.",
   "empty_column.hashtag": "I a pas encara de contengut ligat a aquesta etiqueta.",
   "empty_column.home": "Vòstre flux d’acuèlh es void. Visitatz {public} o utilizatz la recèrca per vos connectar a d’autras personas.",
   "empty_column.home.public_timeline": "lo flux public",
   "empty_column.list": "I a pas res dins la lista pel moment. Quand de membres d’aquesta lista publiquen de novèls estatuts los veiretz aquí.",
+  "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",
   "follow_request.authorize": "Acceptar",
   "follow_request.reject": "Regetar",
   "getting_started.developers": "Desvelopaires",
-  "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Trobar d’amics de Twitter",
+  "getting_started.directory": "Annuari de perfils",
+  "getting_started.documentation": "Documentacion",
   "getting_started.heading": "Per començar",
   "getting_started.invite": "Convidar de monde",
   "getting_started.open_source_notice": "Mastodon es un logicial liure. Podètz contribuir e mandar vòstres comentaris e rapòrt de bug via {github} sus GitHub.",
   "getting_started.security": "Seguretat",
   "getting_started.terms": "Condicions d’utilizacion",
+  "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.tag_mode.all": "Totes aquestes",
+  "hashtag.column_settings.tag_mode.any": "Un d’aquestes",
+  "hashtag.column_settings.tag_mode.none": "Cap d’aquestes",
+  "hashtag.column_settings.tag_toggle": "Inclure las etiquetas suplementàrias dins aquesta colomna",
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Mostrar los partatges",
   "home.column_settings.show_replies": "Mostrar las responsas",
+  "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.",
+  "introduction.federation.home.headline": "Acuèlh",
+  "introduction.federation.home.text": "Los tuts del monde que seguètz apareisseràn dins vòstre flux d’acuèlh. Podètz sègre de monde ont que siasquen !",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Los tuts publics del monde del meteis servidor que vosautres apareisseràn dins lo flux local.",
+  "introduction.interactions.action": "Acabar la leiçon !",
+  "introduction.interactions.favourite.headline": "Favorit",
+  "introduction.interactions.favourite.text": "Podètz enregistrar un tut per mai tard, e avisar l’autor que l’avètz aimat, en l’ajustant als favorits.",
+  "introduction.interactions.reblog.headline": "Partejar",
+  "introduction.interactions.reblog.text": "Podètz partejar los tuts dels autres amb vòstres seguidors en los partejant.",
+  "introduction.interactions.reply.headline": "Respondre",
+  "introduction.interactions.reply.text": "Podètz respondre als tuts dels autres e a vòstres tuts, seràn amassats en una conversacion.",
+  "introduction.welcome.action": "Anem-i !",
+  "introduction.welcome.headline": "Primièrs passes",
+  "introduction.welcome.text": "La benvenguda al fediverse ! D’aquí un momenton, poiretz enviar de messatges e charrar amd d’amics via mantuns servidors. Mas aqueste servidor, {domain}, es especial perque alberga vòstre perfil, doncas oblidatz pas son nom.",
   "keyboard_shortcuts.back": "anar enrèire",
+  "keyboard_shortcuts.blocked": "dobrir la lista d’utilizaires blocats",
   "keyboard_shortcuts.boost": "partejar",
   "keyboard_shortcuts.column": "centrar un estatut a una colomna",
   "keyboard_shortcuts.compose": "anar al camp tèxte",
-  "keyboard_shortcuts.description": "Descripcion",
+  "keyboard_shortcuts.description": "descripcion",
+  "keyboard_shortcuts.direct": "dobrir la colomna de messatges dirèctes",
   "keyboard_shortcuts.down": "far davalar dins la lista",
   "keyboard_shortcuts.enter": "dobrir los estatuts",
   "keyboard_shortcuts.favourite": "apondre als favorits",
+  "keyboard_shortcuts.favourites": "dobrir la lista de favorits",
+  "keyboard_shortcuts.federated": "dobrir lo flux public global",
   "keyboard_shortcuts.heading": "Acorchis clavièr",
+  "keyboard_shortcuts.home": "dobrir lo flux public local",
   "keyboard_shortcuts.hotkey": "Acorchis",
   "keyboard_shortcuts.legend": "mostrar aquesta legenda",
+  "keyboard_shortcuts.local": "dobrir lo flux public local",
   "keyboard_shortcuts.mention": "mencionar l’autor",
+  "keyboard_shortcuts.muted": "dobrir la lista dels utilizaires silenciats",
+  "keyboard_shortcuts.my_profile": "dobrir vòstre perfil",
+  "keyboard_shortcuts.notifications": "dobrir la colomna de notificacions",
+  "keyboard_shortcuts.pinned": "dobrir la lista dels tuts penjats",
+  "keyboard_shortcuts.profile": "dobrir lo perfil de l’autor",
   "keyboard_shortcuts.reply": "respondre",
+  "keyboard_shortcuts.requests": "dorbir la lista de demanda d’abonament",
   "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.toot": "començar un estatut tot novèl",
   "keyboard_shortcuts.unfocus": "quitar lo camp tèxte/de recèrca",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Pas trobat",
   "missing_indicator.sublabel": "Aquesta ressorsa es pas estada trobada",
   "mute_modal.hide_notifications": "Rescondre las notificacions d’aquesta persona ?",
+  "navigation_bar.apps": "Aplicacions mobil",
   "navigation_bar.blocks": "Personas blocadas",
   "navigation_bar.community_timeline": "Flux public local",
+  "navigation_bar.compose": "Escriure un nòu tut",
   "navigation_bar.direct": "Messatges dirèctes",
   "navigation_bar.discover": "Trobar",
   "navigation_bar.domain_blocks": "Domenis resconduts",
   "navigation_bar.edit_profile": "Modificar lo perfil",
   "navigation_bar.favourites": "Favorits",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Mots ignorats",
   "navigation_bar.follow_requests": "Demandas d’abonament",
   "navigation_bar.info": "Mai informacions",
   "navigation_bar.keyboard_shortcuts": "Acorchis clavièr",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Volètz vertadièrament escafar totas vòstras las notificacions ?",
   "notifications.column_settings.alert": "Notificacions localas",
   "notifications.column_settings.favourite": "Favorits :",
+  "notifications.column_settings.filter_bar.advanced": "Mostrar totas las categorias",
+  "notifications.column_settings.filter_bar.category": "Barra de recèrca rapida",
+  "notifications.column_settings.filter_bar.show": "Mostrar",
   "notifications.column_settings.follow": "Nòus seguidors :",
   "notifications.column_settings.mention": "Mencions :",
   "notifications.column_settings.push": "Notificacions",
-  "notifications.column_settings.push_meta": "Aqueste periferic",
   "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.boosts": "Partages",
+  "notifications.filter.favourites": "Favorits",
+  "notifications.filter.follows": "Seguiments",
+  "notifications.filter.mentions": "Mencions",
   "notifications.group": "{count} notificacions",
-  "onboarding.done": "Sortir",
-  "onboarding.next": "Seguent",
-  "onboarding.page_five.public_timelines": "Lo flux local mòstra los estatuts publics del monde de vòstra instància, aquí {domain}. Lo flux federat mòstra los estatuts publics de la gent que los de {domain} sègon. Son los fluxes publics, un bon biais de trobar de mond.",
-  "onboarding.page_four.home": "Lo flux d’acuèlh mòstra los estatuts del monde que seguètz.",
-  "onboarding.page_four.notifications": "La colomna de notificacions vos fa veire quand qualqu’un interagís amb vos.",
-  "onboarding.page_one.federation": "Mastodon es un malhum de servidors independents que comunican per construire un malhum mai larg. Òm los apèla instàncias.",
-  "onboarding.page_one.full_handle": "Vòstre escais-nom complèt",
-  "onboarding.page_one.handle_hint": "Vos cal dire a vòstres amics de cercar aquò.",
-  "onboarding.page_one.welcome": "Benvengut a Mastodon !",
-  "onboarding.page_six.admin": "Vòstre administrator d’instància es {admin}.",
-  "onboarding.page_six.almost_done": "Gaireben acabat…",
-  "onboarding.page_six.appetoot": "Bon Appetut !",
-  "onboarding.page_six.apps_available": "I a d’aplicacions per mobil per iOS, Android e mai.",
-  "onboarding.page_six.github": "Mastodon es un logicial liure e open-source.  Podètz senhalar de bugs, demandar de foncionalitats e contribuir al còdi sus {github}.",
-  "onboarding.page_six.guidelines": "guida de la comunitat",
-  "onboarding.page_six.read_guidelines": "Mercés de legir la {guidelines} de {domain} !",
-  "onboarding.page_six.various_app": "aplicacions per mobil",
-  "onboarding.page_three.profile": "Modificatz vòstre perfil per cambiar vòstre avatar, bio e escais-nom. I a enlà totas las preferéncias.",
-  "onboarding.page_three.search": "Emplegatz la barra de recèrca per trobar de monde e engachatz las etiquetas coma {illustration} e {introductions}. Per trobar una persona d’una autra instància, picatz son identificant complèt.",
-  "onboarding.page_two.compose": "Escrivètz un estatut dempuèi la colomna per compausar. Podètz mandar un imatge, cambiar la confidencialitat e ajustar un avertiment amb las icònas cai-jos.",
-  "onboarding.skip": "Passar",
   "privacy.change": "Ajustar la confidencialitat del messatge",
   "privacy.direct.long": "Mostrar pas qu’a las personas mencionadas",
   "privacy.direct.short": "Dirècte",
@@ -243,17 +285,20 @@
   "search_popout.tips.full_text": "Un tèxte simple que tòrna los estatuts qu’avètz escriches, mes en favorits, partejats, o ont sètz mencionat, e tanben los noms d’utilizaires, escais-noms e etiquetas que correspondonas.",
   "search_popout.tips.hashtag": "etiqueta",
   "search_popout.tips.status": "estatut",
-  "search_popout.tips.text": "Lo tèxt brut tòrna escais, noms d’utilizaire e etiquetas correspondents",
+  "search_popout.tips.text": "Lo tèxte brut tòrna escais, noms d’utilizaire e etiquetas correspondents",
   "search_popout.tips.user": "utilizaire",
   "search_results.accounts": "Gents",
   "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.delete": "Escafar",
+  "status.detailed_status": "Vista detalhada de la convèrsa",
   "status.direct": "Messatge per @{name}",
   "status.embed": "Embarcar",
   "status.favourite": "Apondre als favorits",
@@ -267,9 +312,11 @@
   "status.open": "Desplegar aqueste estatut",
   "status.pin": "Penjar al perfil",
   "status.pinned": "Tut penjat",
+  "status.read_more": "Ne legir mai",
   "status.reblog": "Partejar",
   "status.reblog_private": "Partejar a l’audiéncia d’origina",
   "status.reblogged_by": "{name} a partejat",
+  "status.reblogs.empty": "Degun a pas encara partejat aqueste tut. Quand qualqu’un o farà, apareisserà aquí.",
   "status.redraft": "Escafar e tornar formular",
   "status.reply": "Respondre",
   "status.replyAll": "Respondre a la conversacion",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Los tornar plegar totes",
   "status.show_more": "Desplegar",
   "status.show_more_all": "Los desplegar totes",
+  "status.show_thread": "Mostrar lo fil",
   "status.unmute_conversation": "Tornar mostrar la conversacion",
   "status.unpin": "Tirar del perfil",
+  "suggestions.dismiss": "Regetar la suggestion",
+  "suggestions.header": "Vos poiriá interessar…",
   "tabs_bar.federated_timeline": "Flux public global",
   "tabs_bar.home": "Acuèlh",
   "tabs_bar.local_timeline": "Flux public local",
@@ -291,9 +341,9 @@
   "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",
+  "upload_button.label": "Ajustar un mèdia (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Descripcion pels mal vesents",
-  "upload_form.focus": "Retalhar",
+  "upload_form.focus": "Modificar l’apercebut",
   "upload_form.undo": "Suprimir",
   "upload_progress.label": "Mandadís…",
   "video.close": "Tampar la vidèo",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 4f1290121bc273a142264ad749edef6554c0ad15..0d16f7cfc0554f80289c85dcc12ba683bd68e240 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -1,20 +1,26 @@
 {
+  "account.add_or_remove_from_list": "Dodaj lub usuń z list",
   "account.badges.bot": "Bot",
   "account.block": "Blokuj @{name}",
   "account.block_domain": "Blokuj wszystko z {domain}",
-  "account.blocked": "Zablokowany",
+  "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",
   "account.follow": "Śledź",
   "account.followers": "ÅšledzÄ…cy",
+  "account.followers.empty": "Nikt jeszcze nie śledzi tego użytkownika.",
   "account.follows": "Åšledzeni",
+  "account.follows.empty": "Ten użytkownik nie śledzi jeszcze nikogo.",
   "account.follows_you": "Åšledzi CiÄ™",
   "account.hide_reblogs": "Ukryj podbicia od @{name}",
+  "account.link_verified_on": "Własność tego odnośnika została potwierdzona {date}",
+  "account.locked_info": "To konto jest prywatne. Właściciel ręcznie wybiera kto może go śledzić.",
   "account.media": "Zawartość multimedialna",
   "account.mention": "Wspomnij o @{name}",
-  "account.moved_to": "{name} przeniósł się do:",
+  "account.moved_to": "{name} przeniósł(-osła) się do:",
   "account.mute": "Wycisz @{name}",
   "account.mute_notifications": "Wycisz powiadomienia o @{name}",
   "account.muted": "Wyciszony",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Pokazuj podbicia od @{name}",
   "account.unblock": "Odblokuj @{name}",
   "account.unblock_domain": "Odblokuj domenÄ™ {domain}",
+  "account.unendorse": "Przestań polecać",
   "account.unfollow": "Przestań śledzić",
   "account.unmute": "Cofnij wyciszenie @{name}",
   "account.unmute_notifications": "Cofnij wyciszenie powiadomień od @{name}",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "Wycisz",
   "confirmations.mute.message": "Czy na pewno chcesz wyciszyć {name}?",
   "confirmations.redraft.confirm": "Usuń i przeredaguj",
-  "confirmations.redraft.message": "Czy na pewno chcesz usunąć i przeredagować ten wpis? Utracisz wszystkie odpowiedzi, podbicia i polubienia dotyczące go.",
+  "confirmations.redraft.message": "Czy na pewno chcesz usunąć i przeredagować ten wpis? Polubienia i podbicia zostaną utracone, a odpowiedzi do oryginalnego wpisu zostaną osierocone.",
+  "confirmations.reply.confirm": "Odpowiedz",
+  "confirmations.reply.message": "W ten sposób utracisz wpis który obecnie tworzysz. Czy na pewno chcesz to zrobić?",
   "confirmations.unfollow.confirm": "Przestań śledzić",
   "confirmations.unfollow.message": "Czy na pewno zamierzasz przestać śledzić {name}?",
   "embed.instructions": "Osadź ten wpis na swojej stronie wklejając poniższy kod.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Wyniki wyszukiwania",
   "emoji_button.symbols": "Symbole",
   "emoji_button.travel": "Podróże i miejsca",
+  "empty_column.account_timeline": "Brak wpisów tutaj!",
+  "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.",
-  "empty_column.hashtag": "Nie ma wpisów oznaczonych tym hashtagiem. Możesz napisać pierwszy!",
+  "empty_column.domain_blocks": "Brak ukrytych domen.",
+  "empty_column.favourited_statuses": "Nie dodałeś(-aś) żadnego wpisu do ulubionych. Kiedy to zrobisz, pojawi się on tutaj.",
+  "empty_column.favourites": "Nikt nie dodał tego wpisu do ulubionych. Gdy ktoś to zrobi, pojawi się tutaj.",
+  "empty_column.follow_requests": "Nie masz żadnych próśb o możliwość śledzenia. Kiedy ktoś utworzy ją, pojawi się tutaj.",
+  "empty_column.hashtag": "Nie ma wpisów oznaczonych tym hashtagiem. Możesz napisać pierwszy(-a)!",
   "empty_column.home": "Nie śledzisz nikogo. Odwiedź globalną oś czasu lub użyj wyszukiwarki, aby znaleźć interesujące Cię profile.",
   "empty_column.home.public_timeline": "globalna oÅ› czasu",
   "empty_column.list": "Nie ma nic na tej liście. Kiedy członkowie listy dodadzą nowe wpisy, pojawia się one tutaj.",
+  "empty_column.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ć",
   "follow_request.authorize": "Autoryzuj",
   "follow_request.reject": "Odrzuć",
   "getting_started.developers": "Dla programistów",
+  "getting_started.directory": "Katalog profilów",
   "getting_started.documentation": "Dokumentacja",
-  "getting_started.find_friends": "Znajdź znajomych z Twittera",
   "getting_started.heading": "Rozpocznij",
   "getting_started.invite": "ZaproÅ› znajomych",
   "getting_started.open_source_notice": "Mastodon jest oprogramowaniem o otwartym źródle. Możesz pomóc w rozwoju lub zgłaszać błędy na GitHubie tutaj: {github}.",
   "getting_started.security": "Bezpieczeństwo",
   "getting_started.terms": "Zasady użytkowania",
+  "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.tag_mode.all": "Wszystkie",
+  "hashtag.column_settings.tag_mode.any": "Dowolne",
+  "hashtag.column_settings.tag_mode.none": "Żadne",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Podstawowe",
   "home.column_settings.show_reblogs": "Pokazuj podbicia",
   "home.column_settings.show_replies": "Pokazuj odpowiedzi",
+  "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.",
+  "introduction.federation.home.headline": "Strona główna",
+  "introduction.federation.home.text": "Wpisy osób które śledzisz pojawią się na stronie głównej. Możesz zacząć śledzić użytkowników dowolnego serwera!",
+  "introduction.federation.local.headline": "Lokalna oÅ› czasu",
+  "introduction.federation.local.text": "Publiczne wpisy osób z tego samego serwera pojawiają się na lokalnej osi czasu.",
+  "introduction.interactions.action": "Zakończ poradnik!",
+  "introduction.interactions.favourite.headline": "Ulubione",
+  "introduction.interactions.favourite.text": "Możesz zapisać wpis na później i pokazać autorowi, że Ci się spodobał, jeżeli dodasz go .",
+  "introduction.interactions.reblog.headline": "Podbicia",
+  "introduction.interactions.reblog.text": "Możesz podzielić się wpisem innego użytkownikami z osobami które Cię śledzą podbijając go.",
+  "introduction.interactions.reply.headline": "Odpowiedzi",
+  "introduction.interactions.reply.text": "Możesz odpowiadać na wpisy swoje i innych, tworząc konwersację.",
+  "introduction.welcome.action": "Rozpocznij!",
+  "introduction.welcome.headline": "Pierwsze kroki",
+  "introduction.welcome.text": "Witmay w Fediwersum! Za chwilę dowiesz się, jak przekazywać wiadomości i rozmawiać ze znajomymi pomiędzy różnymi serwerami. Ale ten serwer – {domain} jest wyjątkowy, ponieważ zawiera Twój profil – zapamiętaj więc jego nazwę.",
   "keyboard_shortcuts.back": "aby cofnąć się",
+  "keyboard_shortcuts.blocked": "aby przejść do listy zablokowanych użytkowników",
   "keyboard_shortcuts.boost": "aby podbić wpis",
   "keyboard_shortcuts.column": "aby przejść do wpisu z jednej z kolumn",
   "keyboard_shortcuts.compose": "aby przejść do pola tworzenia wpisu",
   "keyboard_shortcuts.description": "Opis",
+  "keyboard_shortcuts.direct": "aby otworzyć kolumnę wiadomości bezpośrednich",
   "keyboard_shortcuts.down": "aby przejść na dół listy",
   "keyboard_shortcuts.enter": "aby otworzyć wpis",
   "keyboard_shortcuts.favourite": "aby dodać do ulubionych",
+  "keyboard_shortcuts.favourites": "aby przejść do listy ulubionych wpisów",
+  "keyboard_shortcuts.federated": "aby otworzyć oś czasu federacji",
   "keyboard_shortcuts.heading": "Skróty klawiszowe",
+  "keyboard_shortcuts.home": "aby otworzyć stronę główną",
   "keyboard_shortcuts.hotkey": "Klawisz",
-  "keyboard_shortcuts.legend": "aby wyświetlić tą legendę",
+  "keyboard_shortcuts.legend": "aby wyświetlić tę legendę",
+  "keyboard_shortcuts.local": "aby otworzyć lokalną oś czasu",
   "keyboard_shortcuts.mention": "aby wspomnieć o autorze",
+  "keyboard_shortcuts.muted": "aby przejść do listy wyciszonych użytkowników",
+  "keyboard_shortcuts.my_profile": "aby otworzyć własny profil",
+  "keyboard_shortcuts.notifications": "aby otworzyć kolumnę powiadomień",
+  "keyboard_shortcuts.pinned": "aby przejść do listy przypiętych wpisów",
+  "keyboard_shortcuts.profile": "aby przejść do profilu autora wpisu",
   "keyboard_shortcuts.reply": "aby odpowiedzieć",
+  "keyboard_shortcuts.requests": "aby przejść do listy próśb o możliwość śledzenia",
   "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.toot": "aby utworzyć nowy wpis",
   "keyboard_shortcuts.unfocus": "aby opuścić pole wyszukiwania/pisania",
@@ -159,14 +213,16 @@
   "missing_indicator.label": "Nie znaleziono",
   "missing_indicator.sublabel": "Nie można odnaleźć tego zasobu",
   "mute_modal.hide_notifications": "Chcesz ukryć powiadomienia od tego użytkownika?",
+  "navigation_bar.apps": "Aplikacje mobilne",
   "navigation_bar.blocks": "Zablokowani użytkownicy",
   "navigation_bar.community_timeline": "Lokalna oÅ› czasu",
+  "navigation_bar.compose": "Utwórz nowy wpis",
   "navigation_bar.direct": "Wiadomości bezpośrednie",
   "navigation_bar.discover": "Odkrywaj",
   "navigation_bar.domain_blocks": "Ukryte domeny",
   "navigation_bar.edit_profile": "Edytuj profil",
   "navigation_bar.favourites": "Ulubione",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Wyciszone słowa",
   "navigation_bar.follow_requests": "Prośby o śledzenie",
   "navigation_bar.info": "Szczegółowe informacje",
   "navigation_bar.keyboard_shortcuts": "Skróty klawiszowe",
@@ -178,43 +234,29 @@
   "navigation_bar.preferences": "Preferencje",
   "navigation_bar.public_timeline": "Globalna oÅ› czasu",
   "navigation_bar.security": "Bezpieczeństwo",
-  "notification.favourite": "{name} dodał Twój wpis do ulubionych",
-  "notification.follow": "{name} zaczął Cię śledzić",
-  "notification.mention": "{name} wspomniał o tobie",
-  "notification.reblog": "{name} podbił Twój wpis",
+  "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.reblog": "{name} podbił(a) Twój wpis",
   "notifications.clear": "Wyczyść powiadomienia",
   "notifications.clear_confirmation": "Czy na pewno chcesz bezpowrotnie usunąć wszystkie powiadomienia?",
   "notifications.column_settings.alert": "Powiadomienia na pulpicie",
   "notifications.column_settings.favourite": "Dodanie do ulubionych:",
+  "notifications.column_settings.filter_bar.advanced": "Wyświetl wszystkie kategorie",
+  "notifications.column_settings.filter_bar.category": "Szybkie filtrowanie",
+  "notifications.column_settings.filter_bar.show": "Pokaż",
   "notifications.column_settings.follow": "Nowi śledzący:",
   "notifications.column_settings.mention": "Wspomnienia:",
   "notifications.column_settings.push": "Powiadomienia push",
-  "notifications.column_settings.push_meta": "To urzÄ…dzenie",
   "notifications.column_settings.reblog": "Podbicia:",
   "notifications.column_settings.show": "Pokaż w kolumnie",
   "notifications.column_settings.sound": "Odtwarzaj dźwięk",
+  "notifications.filter.all": "Wszystkie",
+  "notifications.filter.boosts": "Podbicia",
+  "notifications.filter.favourites": "Ulubione",
+  "notifications.filter.follows": "Åšledzenia",
+  "notifications.filter.mentions": "Wspomienia",
   "notifications.group": "{count, number} {count, plural, one {powiadomienie} few {powiadomienia} many {powiadomień} more {powiadomień}}",
-  "onboarding.done": "Gotowe",
-  "onboarding.next": "Dalej",
-  "onboarding.page_five.public_timelines": "Lokalna oś czasu zawiera wszystkie publiczne wpisy z {domain}. Globalna oś czasu wyświetla publiczne wpisy śledzonych przez członków {domain}. Są to publiczne osie czasu – najlepszy sposób na poznanie nowych osób.",
-  "onboarding.page_four.home": "Główna oś czasu wyświetla publiczne wpisy.",
-  "onboarding.page_four.notifications": "Kolumna powiadomień wyświetla, gdy ktoś dokonuje interakcji z tobą.",
-  "onboarding.page_one.federation": "Mastodon jest siecią niezależnych serwerów połączonych w jeden portal społecznościowy. Nazywamy te serwery instancjami.",
-  "onboarding.page_one.full_handle": "Twój pełny adres",
-  "onboarding.page_one.handle_hint": "Należy go podać znajomym, aby mogli Cię odnaleźć.",
-  "onboarding.page_one.welcome": "Witamy w Mastodon!",
-  "onboarding.page_six.admin": "Administratorem tej instancji jest {admin}.",
-  "onboarding.page_six.almost_done": "Prawie gotowe…",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Są dostępne {apps} dla Androida, iOS i innych platform.",
-  "onboarding.page_six.github": "Mastodon jest oprogramowaniem otwartoźródłwym. Możesz zgłaszać błędy, proponować funkcje i pomóc w rozwoju na {github}.",
-  "onboarding.page_six.guidelines": "wytyczne dla społeczności",
-  "onboarding.page_six.read_guidelines": "Przeczytaj {guidelines} {domain}!",
-  "onboarding.page_six.various_app": "aplikacje mobilne",
-  "onboarding.page_three.profile": "Edytuj profil, aby zmienić obraz profilowy, biografię, wyświetlaną nazwę i inne ustawienia.",
-  "onboarding.page_three.search": "Użyj paska wyszukiwania aby znaleźć ludzi i hashtagi, takie jak {illustration} i {introductions}. Aby znaleźć osobę spoza tej instancji, musisz użyć pełnego adresu.",
-  "onboarding.page_two.compose": "Utwórz wpisy, aby wypełnić kolumnę. Możesz wysłać zdjęcia, zmienić ustawienia prywatności lub dodać ostrzeżenie o zawartości.",
-  "onboarding.skip": "Pomiń",
   "privacy.change": "Dostosuj widoczność wpisów",
   "privacy.direct.long": "Widoczny tylko dla wspomnianych",
   "privacy.direct.short": "Bezpośrednio",
@@ -234,13 +276,13 @@
   "reply_indicator.cancel": "Anuluj",
   "report.forward": "Przekaż na {target}",
   "report.forward_hint": "To konto znajduje się na innej instancji. Czy chcesz wysłać anonimową kopię zgłoszenia rnież na nią?",
-  "report.hint": "Zgłoszenie zostanie wysłane moderatorom Twojej instancji. Poniżej możesz też umieścić wyjaśnieni dlaczego zgłaszasz to konto:",
+  "report.hint": "Zgłoszenie zostanie wysłane moderatorom Twojej instancji. 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ś, dodałeś do ulubionych, podbiłeś w których o Tobie wspomniano, oraz pasujące nazwy użytkowników, pełne nazwy i hashtagi.",
+  "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.status": "wpis",
   "search_popout.tips.text": "Proste wyszukiwanie pasujących pseudonimów, nazw użytkowników i hashtagów",
@@ -250,14 +292,17 @@
   "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.delete": "Usuń",
+  "status.detailed_status": "Szczegółowy widok konwersacji",
   "status.direct": "Wyślij wiadomość bezpośrednią do @{name}",
   "status.embed": "Osadź",
   "status.favourite": "Dodaj do ulubionych",
-  "status.filtered": "Filtrowany",
+  "status.filtered": "Filtrowany(-a)",
   "status.load_more": "Załaduj więcej",
   "status.media_hidden": "Zawartość multimedialna ukryta",
   "status.mention": "Wspomnij o @{name}",
@@ -267,9 +312,11 @@
   "status.open": "Rozszerz ten wpis",
   "status.pin": "Przypnij do profilu",
   "status.pinned": "Przypięty wpis",
+  "status.read_more": "Czytaj dalej",
   "status.reblog": "Podbij",
   "status.reblog_private": "Podbij dla odbiorców oryginalnego wpisu",
-  "status.reblogged_by": "{name} podbił",
+  "status.reblogged_by": "{name} podbił(a)",
+  "status.reblogs.empty": "Nikt nie podbił jeszcze tego wpisu. Gdy ktoś to zrobi, pojawi się tutaj.",
   "status.redraft": "Usuń i przeredaguj",
   "status.reply": "Odpowiedz",
   "status.replyAll": "Odpowiedz na wÄ…tek",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Zwiń wszystkie",
   "status.show_more": "Rozwiń",
   "status.show_more_all": "Rozwiń wszystkie",
+  "status.show_thread": "Pokaż wątek",
   "status.unmute_conversation": "Cofnij wyciszenie konwersacji",
   "status.unpin": "Odepnij z profilu",
+  "suggestions.dismiss": "Odrzuć sugestię",
+  "suggestions.header": "Może Cię zainteresować…",
   "tabs_bar.federated_timeline": "Globalne",
   "tabs_bar.home": "Strona główna",
   "tabs_bar.local_timeline": "Lokalne",
@@ -291,11 +341,11 @@
   "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ą",
+  "upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących",
-  "upload_form.focus": "Przytnij",
+  "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 4ee02f75750edf9405857d3eea96931632b31f6f..392e7f485d2483091d1fa5a52e2e3a83f24b6a21 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Adicionar ou remover de listas",
   "account.badges.bot": "Robô",
   "account.block": "Bloquear @{name}",
   "account.block_domain": "Esconder tudo de {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
+  "account.followers.empty": "Ninguém segue esse usuário no momento.",
   "account.follows": "Segue",
+  "account.follows.empty": "Esse usuário não segue ninguém no momento.",
   "account.follows_you": "Segue você",
   "account.hide_reblogs": "Esconder compartilhamentos de @{name}",
+  "account.link_verified_on": "A posse desse link foi verificada em {date}",
+  "account.locked_info": "Essa conta está trancada. Se você a seguir sua solicitação será revisada manualmente.",
   "account.media": "Mídia",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} se mudou para:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Mostra compartilhamentos de @{name}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Desbloquear {domain}",
+  "account.unendorse": "Não destacar no perfil",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Não silenciar @{name}",
   "account.unmute_notifications": "Retirar silêncio das notificações vindas de @{name}",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "Silenciar",
   "confirmations.mute.message": "Você tem certeza de que quer silenciar {name}?",
   "confirmations.redraft.confirm": "Apagar & usar como rascunho",
-  "confirmations.redraft.message": "Você tem certeza que deseja apagar esse status e usá-lo como rascunho? Você vai perder todas as respostas, compartilhamentos e favoritos relacionados a ele.",
+  "confirmations.redraft.message": "Você tem certeza que deseja apagar esse status e usá-lo como rascunho? Seus compartilhamentos e favoritos serão perdidos e as respostas ao toot original ficarão desconectadas.",
+  "confirmations.reply.confirm": "Responder",
+  "confirmations.reply.message": "Responder agora vai sobrescrever a mensagem que você está compondo. Você tem certeza que quer continuar?",
   "confirmations.unfollow.confirm": "Deixar de seguir",
   "confirmations.unfollow.message": "Você tem certeza de que quer deixar de seguir {name}?",
   "embed.instructions": "Incorpore esta postagem em seu site copiando o código abaixo.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Resultados da busca",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viagens & Lugares",
+  "empty_column.account_timeline": "Não há toots aqui!",
+  "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.",
+  "empty_column.domain_blocks": "Ainda não há nenhum domínio escondido.",
+  "empty_column.favourited_statuses": "Você ainda não tem nenhum toot favorito. Quando você favoritar um toot, ele aparecerá aqui.",
+  "empty_column.favourites": "Ninguém favoritou esse toot até agora. Quando alguém favoritar, a pessoa aparecerá aqui.",
+  "empty_column.follow_requests": "Você não tem nenhum pedido de seguir por agora. Quando você receber um, ele aparecerá aqui.",
   "empty_column.hashtag": "Ainda não há qualquer conteúdo com essa hashtag.",
   "empty_column.home": "Você ainda não segue usuário algum. Visite a timeline {public} ou use o buscador para procurar e conhecer outros usuários.",
   "empty_column.home.public_timeline": "global",
   "empty_column.list": "Ainda não há nada nesta lista. Quando membros dessa lista fizerem novas postagens, elas aparecerão aqui.",
+  "empty_column.lists": "Você ainda não tem nenhuma lista. Quando você criar uma, ela aparecerá aqui.",
+  "empty_column.mutes": "Você ainda não silenciou nenhum usuário.",
   "empty_column.notifications": "Você ainda não possui notificações. Interaja com outros usuários para começar a conversar.",
   "empty_column.public": "Não há nada aqui! Escreva algo publicamente ou siga manualmente usuários de outras instâncias",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rejeitar",
   "getting_started.developers": "Desenvolvedores",
-  "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Encontre amizades do Twitter",
+  "getting_started.directory": "Diretório de perfis",
+  "getting_started.documentation": "Documentação",
   "getting_started.heading": "Primeiros passos",
   "getting_started.invite": "Convide pessoas",
   "getting_started.open_source_notice": "Mastodon é um software de código aberto. Você pode contribuir ou reportar problemas na página do GitHub do projeto: {github}.",
   "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.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",
   "home.column_settings.basic": "Básico",
   "home.column_settings.show_reblogs": "Mostrar compartilhamentos",
   "home.column_settings.show_replies": "Mostrar as respostas",
+  "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.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "Posts de pessoas que você segue vão aparecer na sua página inicial. Você pode seguir pessoas de qualquer servidor!",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Posts públicos de pessoas no mesmo servidor que você vão aparecer na timeline local.",
+  "introduction.interactions.action": "Finalizar o tutorial!",
+  "introduction.interactions.favourite.headline": "Favoritos",
+  "introduction.interactions.favourite.text": "Você pode salvar um toot pra mais tarde, e deixar a pessoa que postou saber que você gostou, favoritando-o.",
+  "introduction.interactions.reblog.headline": "Compartilhamento",
+  "introduction.interactions.reblog.text": "Você pode mostrar toots de outras pessoas aos seus seguidores compartilhando.",
+  "introduction.interactions.reply.headline": "Responder",
+  "introduction.interactions.reply.text": "Você pode responder a toots de outras pessoas e aos seus, e isso vai uni-los em uma conversa.",
+  "introduction.welcome.action": "Vamos!",
+  "introduction.welcome.headline": "Primeiros passos",
+  "introduction.welcome.text": "Boas vindas ao fediverso! Em alguns momentos, você vai poder transmitir mensagens e falar com pessoas amigas através de uma variedade de servidores. Mas esse servidor, {domain}, é especial—é onde o seu perfil está hospedado, então lembre do nome.",
   "keyboard_shortcuts.back": "para navegar de volta",
+  "keyboard_shortcuts.blocked": "para abrir a lista de usuários bloqueados",
   "keyboard_shortcuts.boost": "para compartilhar",
   "keyboard_shortcuts.column": "Focar um status em uma das colunas",
   "keyboard_shortcuts.compose": "para focar a área de redação",
-  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.description": "Descrição",
+  "keyboard_shortcuts.direct": "para abrir a coluna de mensagens diretas",
   "keyboard_shortcuts.down": "para mover para baixo na lista",
-  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.enter": "para expandir um status",
   "keyboard_shortcuts.favourite": "para adicionar aos favoritos",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "keyboard_shortcuts.favourites": "para abrir a lista de favoritos",
+  "keyboard_shortcuts.federated": "para abrir a timeline global",
+  "keyboard_shortcuts.heading": "Atalhos de teclado",
+  "keyboard_shortcuts.home": "para abrir a página inicial",
   "keyboard_shortcuts.hotkey": "Atalho",
   "keyboard_shortcuts.legend": "para mostrar essa legenda",
+  "keyboard_shortcuts.local": "para abrir a timeline local",
   "keyboard_shortcuts.mention": "para mencionar o autor",
+  "keyboard_shortcuts.muted": "para abrir a lista de usuários silenciados",
+  "keyboard_shortcuts.my_profile": "para abrir o seu perfil",
+  "keyboard_shortcuts.notifications": "para abrir a coluna de notificações",
+  "keyboard_shortcuts.pinned": "para abrir a lista de toots fixados",
+  "keyboard_shortcuts.profile": "para abrir o perfil do autor",
   "keyboard_shortcuts.reply": "para responder",
+  "keyboard_shortcuts.requests": "para abrir a lista de seguidores pendentes",
   "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.toot": "para compor um novo toot",
   "keyboard_shortcuts.unfocus": "para remover o foco da área de composição/pesquisa",
@@ -159,21 +213,23 @@
   "missing_indicator.label": "Não encontrado",
   "missing_indicator.sublabel": "Esse recurso não pôde ser encontrado",
   "mute_modal.hide_notifications": "Esconder notificações deste usuário?",
+  "navigation_bar.apps": "Apps",
   "navigation_bar.blocks": "Usuários bloqueados",
   "navigation_bar.community_timeline": "Local",
+  "navigation_bar.compose": "Compor um novo toot",
   "navigation_bar.direct": "Mensagens diretas",
   "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.keyboard_shortcuts": "Atalhos de teclado",
   "navigation_bar.lists": "Listas",
   "navigation_bar.logout": "Sair",
   "navigation_bar.mutes": "Usuários silenciados",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Pessoal",
   "navigation_bar.pins": "Postagens fixadas",
   "navigation_bar.preferences": "Preferências",
   "navigation_bar.public_timeline": "Global",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Você tem certeza de que quer limpar todas as suas notificações permanentemente?",
   "notifications.column_settings.alert": "Notificações no computador",
   "notifications.column_settings.favourite": "Favoritos:",
+  "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias",
+  "notifications.column_settings.filter_bar.category": "Barra de filtro rápido",
+  "notifications.column_settings.filter_bar.show": "Mostrar",
   "notifications.column_settings.follow": "Novos seguidores:",
   "notifications.column_settings.mention": "Menções:",
   "notifications.column_settings.push": "Enviar notificações",
-  "notifications.column_settings.push_meta": "Este aparelho",
   "notifications.column_settings.reblog": "Compartilhamento:",
   "notifications.column_settings.show": "Mostrar nas colunas",
   "notifications.column_settings.sound": "Reproduzir som",
+  "notifications.filter.all": "Tudo",
+  "notifications.filter.boosts": "Compartilhamentos",
+  "notifications.filter.favourites": "Favoritos",
+  "notifications.filter.follows": "Seguidores",
+  "notifications.filter.mentions": "Menções",
   "notifications.group": "{count} notificações",
-  "onboarding.done": "Pronto",
-  "onboarding.next": "Próximo",
-  "onboarding.page_five.public_timelines": "A timeline local mostra postagens públicas de todos os usuários no {domain}. A timeline federada mostra todas as postagens de todas as pessoas que pessoas no {domain} seguem. Estas são as timelines públicas, uma ótima maneira de conhecer novas pessoas.",
-  "onboarding.page_four.home": "A página inicial mostra postagens de pessoas que você segue.",
-  "onboarding.page_four.notifications": "A coluna de notificações te mostra quando alguém interage com você.",
-  "onboarding.page_one.federation": "Mastodon é uma rede de servidores independentes que se juntam para fazer uma grande rede social. Nós chamamos estes servidores de instâncias.",
-  "onboarding.page_one.full_handle": "Seu nome de usuário completo",
-  "onboarding.page_one.handle_hint": "Isso é o que você diz aos seus amigos para que eles possam te mandar mensagens ou te seguir a partir de outra instância.",
-  "onboarding.page_one.welcome": "Boas-vindas ao Mastodon!",
-  "onboarding.page_six.admin": "O administrador de sua instância é {admin}.",
-  "onboarding.page_six.almost_done": "Quase acabando...",
-  "onboarding.page_six.appetoot": "Bom Apetoot!",
-  "onboarding.page_six.apps_available": "Há {apps} disponíveis para iOS, Android e outras plataformas.",
-  "onboarding.page_six.github": "Mastodon é um software gratuito e de código aberto. Você pode reportar bugs, prequisitar novas funções ou contribuir para o código no {github}.",
-  "onboarding.page_six.guidelines": "diretrizes da comunidade",
-  "onboarding.page_six.read_guidelines": "Por favor, leia as {guidelines} do {domain}!",
-  "onboarding.page_six.various_app": "aplicativos móveis",
-  "onboarding.page_three.profile": "Edite o seu perfil para mudar o seu o seu avatar, bio e nome de exibição. No menu de configurações, você também encontrará outras preferências.",
-  "onboarding.page_three.search": "Use a barra de buscas para encontrar pessoas e consultar hashtags, como #illustrations e #introductions. Para procurar por uma pessoa que não estiver nesta instância, use o nome de usuário completo dela.",
-  "onboarding.page_two.compose": "Escreva postagens na coluna de escrita. Você pode hospedar imagens, mudar as configurações de privacidade e adicionar alertas de conteúdo através dos ícones abaixo.",
-  "onboarding.skip": "Pular",
   "privacy.change": "Ajustar a privacidade da mensagem",
   "privacy.direct.long": "Apenas para usuários mencionados",
   "privacy.direct.short": "Direta",
@@ -250,10 +292,13 @@
   "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.delete": "Excluir",
+  "status.detailed_status": "Visão detalhada da conversa",
   "status.direct": "Enviar mensagem direta a @{name}",
   "status.embed": "Incorporar",
   "status.favourite": "Adicionar aos favoritos",
@@ -267,9 +312,11 @@
   "status.open": "Expandir",
   "status.pin": "Fixar no perfil",
   "status.pinned": "Toot fixado",
+  "status.read_more": "Ler mais",
   "status.reblog": "Compartilhar",
   "status.reblog_private": "Compartilhar com a audiência original",
   "status.reblogged_by": "{name} compartilhou",
+  "status.reblogs.empty": "Ninguém compartilhou esse toot até agora. Quando alguém o fizer, eles aparecerão aqui.",
   "status.redraft": "Apagar & usar como rascunho",
   "status.reply": "Responder",
   "status.replyAll": "Responder à sequência",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Mostrar menos para todas as mensagens",
   "status.show_more": "Mostrar mais",
   "status.show_more_all": "Mostrar mais para todas as mensagens",
+  "status.show_thread": "Mostrar sequência",
   "status.unmute_conversation": "Desativar silêncio desta conversa",
   "status.unpin": "Desafixar do perfil",
+  "suggestions.dismiss": "Ignorar a sugestão",
+  "suggestions.header": "Você pode se interessar por…",
   "tabs_bar.federated_timeline": "Global",
   "tabs_bar.home": "Página inicial",
   "tabs_bar.local_timeline": "Local",
@@ -291,7 +341,7 @@
   "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",
+  "upload_button.label": "Adicionar mídia (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "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 686c05d729d9ce1a2b7922f333379c80a6c10f02..d4126704a2fcff0179efac7d5c2b45e080fadb1c 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Bloquear @{name}",
   "account.block_domain": "Esconder tudo do domínio {domain}",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de forma incompleta.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Editar perfil",
+  "account.endorse": "Feature on profile",
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Segue",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "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.media": "Media",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} mudou a sua conta para:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Mostrar partilhas de @{name}",
   "account.unblock": "Não bloquear @{name}",
   "account.unblock_domain": "Mostrar {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Não silenciar @{name}",
   "account.unmute_notifications": "Deixar de silenciar @{name}",
@@ -86,6 +93,8 @@
   "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.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.",
@@ -104,41 +113,86 @@
   "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.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.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.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.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",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rejeitar",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Primeiros passos",
   "getting_started.invite": "Invite people",
   "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",
   "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",
+  "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": "para voltar",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
   "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.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.heading": "Atalhos do teclado",
+  "keyboard_shortcuts.home": "to open home timeline",
   "keyboard_shortcuts.hotkey": "Atalho",
   "keyboard_shortcuts.legend": "para mostrar esta legenda",
+  "keyboard_shortcuts.local": "to open local timeline",
   "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.reply": "para responder",
+  "keyboard_shortcuts.requests": "to open follow requests list",
   "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.toot": "para compor um novo post",
   "keyboard_shortcuts.unfocus": "para remover o foco da área de publicação/pesquisa",
@@ -159,8 +213,10 @@
   "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.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",
@@ -186,35 +242,21 @@
   "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.follow": "Novos seguidores:",
   "notifications.column_settings.mention": "Menções:",
   "notifications.column_settings.push": "Notificações Push",
-  "notifications.column_settings.push_meta": "Este dispositivo",
   "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",
-  "onboarding.done": "Pronto",
-  "onboarding.next": "Próximo",
-  "onboarding.page_five.public_timelines": "A timeline local mostra as publicações de todos os utilizadores em {domain}. A timeline global mostra as publicações de todas as pessoas que pessoas em {domain} seguem. Estas são as timelines públicas, uma óptima forma de conhecer novas pessoas.",
-  "onboarding.page_four.home": "A timeline home mostra as publicações de pessoas que tu segues.",
-  "onboarding.page_four.notifications": "A coluna de notificações mostra-te quando alguém interage contigo.",
-  "onboarding.page_one.federation": "Mastodon é uma rede de servidores independentes ligados entre si para fazer uma grande rede social. Nós chamamos instâncias a estes servidores.",
-  "onboarding.page_one.full_handle": "O teu nome de utilizador completo",
-  "onboarding.page_one.handle_hint": "Isto é o que dizes aos teus amigos para pesquisar.",
-  "onboarding.page_one.welcome": "Boas-vindas ao Mastodon!",
-  "onboarding.page_six.admin": "O administrador da tua instância é {admin}.",
-  "onboarding.page_six.almost_done": "Quase pronto...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Existem {apps} disponíveis para iOS, Android e outras plataformas.",
-  "onboarding.page_six.github": "Mastodon é um software gratuito e de código aberto. Podes reportar bugs, solicitar novas funcionalidades e contribuir para o código em {github}.",
-  "onboarding.page_six.guidelines": "termos de utilização da comunidade",
-  "onboarding.page_six.read_guidelines": "Por favor, lê os {guidelines} de {domain}!",
-  "onboarding.page_six.various_app": "aplicações de telemóvel",
-  "onboarding.page_three.profile": "Edita o teu perfil para mudar a tua imagem, biografia e nome. Lá encontrarás também outras preferências que podes personalizar.",
-  "onboarding.page_three.search": "Utiliza a caixa de pesquisa para procurar pessoas ou hashtags, exemplo {illustration} / {introductions}. Para procurar uma pessoa que não está nesta instância, utiliza o endereço completo.",
-  "onboarding.page_two.compose": "Escreve posts na coluna de publicações. Podes publicar imagens, alterar a privacidade e adicionar alertas de conteúdo usando os ícones abaixo da caixa de composição.",
-  "onboarding.skip": "Saltar",
   "privacy.change": "Ajustar a privacidade da mensagem",
   "privacy.direct.long": "Apenas para utilizadores mencionados",
   "privacy.direct.short": "Directo",
@@ -250,10 +292,13 @@
   "search_results.statuses": "Toots",
   "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.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Este post não pode ser partilhado",
   "status.delete": "Eliminar",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Incorporar",
   "status.favourite": "Adicionar aos favoritos",
@@ -267,9 +312,11 @@
   "status.open": "Expandir",
   "status.pin": "Fixar no perfil",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "Partilhar",
   "status.reblog_private": "Boost to original audience",
   "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.reply": "Responder",
   "status.replyAll": "Responder à conversa",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Mostrar mais",
   "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
   "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…",
   "tabs_bar.federated_timeline": "Global",
   "tabs_bar.home": "Home",
   "tabs_bar.local_timeline": "Local",
diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json
new file mode 100644
index 0000000000000000000000000000000000000000..a1a514f4948b5f2878b561fbdf039f51b68c9492
--- /dev/null
+++ b/app/javascript/mastodon/locales/ro.json
@@ -0,0 +1,358 @@
+{
+  "account.add_or_remove_from_list": "Adaugă sau Elimină din liste",
+  "account.badges.bot": "Bot",
+  "account.block": "Blochează @{name}",
+  "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",
+  "account.follow": "Urmărește",
+  "account.followers": "Urmăritori",
+  "account.followers.empty": "Acest utilizator nu are încă urmăritori.",
+  "account.follows": "Urmărește",
+  "account.follows.empty": "Acest utilizator nu urmărește pe nimeni incă.",
+  "account.follows_you": "Te urmărește",
+  "account.hide_reblogs": "Ascunde redistribuirile de la @{name}",
+  "account.link_verified_on": "Deținerea acestui link a fost verificată la {date}",
+  "account.locked_info": "Acest profil este privat. Această persoană gestioneaz manual cine o urmărește.",
+  "account.media": "Media",
+  "account.mention": "Menționează @{name}",
+  "account.moved_to": "{name} a fost mutat la:",
+  "account.mute": "Oprește @{name}",
+  "account.mute_notifications": "Oprește notificările de la @{name}",
+  "account.muted": "Oprit",
+  "account.posts": "Postări",
+  "account.posts_with_replies": "Postări și replici",
+  "account.report": "Raportează @{name}",
+  "account.requested": "Se așteaptă aprobarea. Apasă pentru a anula cererea de urmărire",
+  "account.share": "Distribuie profilul lui @{name}",
+  "account.show_reblogs": "Arată redistribuirile de la @{name}",
+  "account.unblock": "Deblochează @{name}",
+  "account.unblock_domain": "Arată {domain}",
+  "account.unendorse": "Nu promova pe profil",
+  "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",
+  "bundle_column_error.body": "Ceva nu a funcționat la încărcarea acestui component.",
+  "bundle_column_error.retry": "Încearcă din nou",
+  "bundle_column_error.title": "Eroare de rețea",
+  "bundle_modal_error.close": "ÃŽnchide",
+  "bundle_modal_error.message": "Ceva nu a funcționat în timupul încărcării acestui component.",
+  "bundle_modal_error.retry": "Încearcă din nou",
+  "column.blocks": "Utilizatori blocați",
+  "column.community": "Fluxul Local",
+  "column.direct": "Mesaje directe",
+  "column.domain_blocks": "Domenii ascunse",
+  "column.favourites": "Favorite",
+  "column.follow_requests": "Cereri de urmărire",
+  "column.home": "Acasă",
+  "column.lists": "Liste",
+  "column.mutes": "Utilizatori opriți",
+  "column.notifications": "Notificări",
+  "column.pins": "Postări fixate",
+  "column.public": "Flux global",
+  "column_back_button.label": "ÃŽnapoi",
+  "column_header.hide_settings": "Ascunde setările",
+  "column_header.moveLeft_settings": "Mută coloana la stânga",
+  "column_header.moveRight_settings": "Mută coloana la dreapta",
+  "column_header.pin": "Fixează",
+  "column_header.show_settings": "Arată setările",
+  "column_header.unpin": "Eliberează",
+  "column_subheading.settings": "Setări",
+  "community.column_settings.media_only": "Doar media",
+  "compose_form.direct_message_warning": "Această postare va fi trimisă doar utilizatorilor menționați.",
+  "compose_form.direct_message_warning_learn_more": "Află mai multe",
+  "compose_form.hashtag_warning": "Această postare nu va fi listată sub nici un hastag. Doar postările publice pot fi găsite dupa un hastag.",
+  "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.publish": "Postează",
+  "compose_form.publish_loud": "{publish}!",
+  "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.confirm": "Blochează",
+  "confirmations.block.message": "Ești sigur că vrei să blochezi {name}?",
+  "confirmations.delete.confirm": "Șterge",
+  "confirmations.delete.message": "Ești șigur că vrei să ștergi asta?",
+  "confirmations.delete_list.confirm": "Șterge",
+  "confirmations.delete_list.message": "Ești sigur că vrei să ștergi permanent această listă?",
+  "confirmations.domain_block.confirm": "Ascunde tot domeniul",
+  "confirmations.domain_block.message": "Ești absolut sigur că vrei să blochezi complet {domain}? În cele mai multe cazuri raportarea sau oprirea anumitor lucruri este suficientă și de preferat. Nu vei mai vedea nici un conținut de la acest domeniu in nici un flux public sau în notificările tale. Urmăritorii tăi de la acele domenii vor fi eliminați.",
+  "confirmations.mute.confirm": "Oprește",
+  "confirmations.mute.message": "Ești sigur că vrei să oprești {name}?",
+  "confirmations.redraft.confirm": "Șterge și salvează ca ciornă",
+  "confirmations.redraft.message": "Ești sigur că vrei să faci asta? Tot ce ține de această postare, inclusiv răspunsurile vor fi deconectate.",
+  "confirmations.reply.confirm": "Răspunde",
+  "confirmations.reply.message": "Răspunzând la asta acum, mesajul pe care îl compui în prezent se va șterge. Ești sigur că vrei să continui?",
+  "confirmations.unfollow.confirm": "Nu mai urmări",
+  "confirmations.unfollow.message": "Ești sigur că nu mai vrei să îl urmărești pe {name}?",
+  "embed.instructions": "Inserează această postare pe site-ul tău adăugând codul de mai jos.",
+  "embed.preview": "Cam așa va arăta:",
+  "emoji_button.activity": "Activitate",
+  "emoji_button.custom": "Personalizat",
+  "emoji_button.flags": "Marcaje",
+  "emoji_button.food": "Mâncare și Băuturi",
+  "emoji_button.label": "Inserează un emoji",
+  "emoji_button.nature": "Natură",
+  "emoji_button.not_found": "Fară emojiuri (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Obiecte",
+  "emoji_button.people": "Persoane",
+  "emoji_button.recent": "Utilizate frecvent",
+  "emoji_button.search": "Caută...",
+  "emoji_button.search_results": "Rezultatele căutării",
+  "emoji_button.symbols": "Simboluri",
+  "emoji_button.travel": "Călătorii si Locuri",
+  "empty_column.account_timeline": "Nici o postare aici!",
+  "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.",
+  "empty_column.domain_blocks": "Nu sunt domenii ascunse incă.",
+  "empty_column.favourited_statuses": "Nu ai nici o postare favorită încă. Când vei avea, vor fi afișate aici.",
+  "empty_column.favourites": "Nimeni nu are această postare adăugată la favorite. Când cineva o va face va fi afișat aici.",
+  "empty_column.follow_requests": "Nu ai încă nici o cerere de urmărire. Când vei primi una, va fi afișată aici.",
+  "empty_column.hashtag": "Acest hastag nu a fost folosit încă.",
+  "empty_column.home": "Fluxul tău este gol. Vizitează {public} sau fă o căutare pentru a începe să cunoști oameni noi.",
+  "empty_column.home.public_timeline": "fluxul public",
+  "empty_column.list": "Nu este nimic încă în această listă. Când membrii acestei liste vor începe să posteze, va apărea aici.",
+  "empty_column.lists": "Nu ai încă nici o listă. Când vei crea una, va apărea aici.",
+  "empty_column.mutes": "Nu ai oprit nici un utilizator incă.",
+  "empty_column.notifications": "Nu ai nici o notificare încă. Interacționează cu alții pentru a începe o conversație.",
+  "empty_column.public": "Nu este nimci aici încă! Scrie ceva public, sau urmărește alți utilizatori din alte instanțe pentru a porni fluxul",
+  "follow_request.authorize": "Autorizează",
+  "follow_request.reject": "Respinge",
+  "getting_started.developers": "Dezvoltatori",
+  "getting_started.directory": "Explorează",
+  "getting_started.documentation": "Documentație",
+  "getting_started.heading": "ÃŽncepe",
+  "getting_started.invite": "Invită prieteni",
+  "getting_started.open_source_notice": "Mastodon este o rețea de socializare de tip open source. Puteți contribuii la dezvoltarea ei sau să semnalați erorile pe GitHub la {github}.",
+  "getting_started.security": "Securitate",
+  "getting_started.terms": "Termeni de Utilizare",
+  "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.tag_mode.all": "Toate acestea",
+  "hashtag.column_settings.tag_mode.any": "Oricare din acestea",
+  "hashtag.column_settings.tag_mode.none": "Niciuna din aceastea",
+  "hashtag.column_settings.tag_toggle": "Adaugă etichete adiționale pentru această coloană",
+  "home.column_settings.basic": "De bază",
+  "home.column_settings.show_reblogs": "Arată redistribuirile",
+  "home.column_settings.show_replies": "Arată răspunsurile",
+  "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.",
+  "introduction.federation.home.headline": "Acasă",
+  "introduction.federation.home.text": "Postările de la persoanele pe care le urmărești vor apărea in fluxul tău \"Acasă\". Poți urmări pe orice de pe orice server!",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Postările publice de la persoanele de pe acest server vor apărea în fluxul local.",
+  "introduction.interactions.action": "ÃŽncheie ghidul!",
+  "introduction.interactions.favourite.headline": "Favorite",
+  "introduction.interactions.favourite.text": "Poți salva o postare pentru a fi citită mai târziu și poți lăsa autorul să știe că iți place adăugândo la favorite.",
+  "introduction.interactions.reblog.headline": "Redistribuie",
+  "introduction.interactions.reblog.text": "Poți împărtăși postările altora cu urmăritorii tăi redistribuindule.",
+  "introduction.interactions.reply.headline": "Răspunde",
+  "introduction.interactions.reply.text": "Poți răspunde la postările tale și alte altora, care se vor lărgii în discuții.",
+  "introduction.welcome.action": "Să începem!",
+  "introduction.welcome.headline": "Primii pași",
+  "introduction.welcome.text": "Bun Venit in federație! In câteva momente, vei putea să transmiți mesaje și să participi la discuții cu oameni noi intr-o varietate foarte largă de servere din întreaga lume. Dar în special acest server, {domain},găzduiește profilul tău, deci reține numele acestuia.",
+  "keyboard_shortcuts.back": "navighează inapoi",
+  "keyboard_shortcuts.blocked": "să deschidă lista utilizatorilor blocați",
+  "keyboard_shortcuts.boost": "să redistribuie",
+  "keyboard_shortcuts.column": "să focuzeze o postare in una dintre coloane",
+  "keyboard_shortcuts.compose": "sa focuzeze zona de compunere",
+  "keyboard_shortcuts.description": "Descriere",
+  "keyboard_shortcuts.direct": "să deschidă coloana de mesaje directe",
+  "keyboard_shortcuts.down": "să fie mutată jos in lista",
+  "keyboard_shortcuts.enter": "să deschidă un status",
+  "keyboard_shortcuts.favourite": "să adauge la favorite",
+  "keyboard_shortcuts.favourites": "să deschidă lista cu favorite",
+  "keyboard_shortcuts.federated": "să deschidă fluxul global",
+  "keyboard_shortcuts.heading": "Comenzi rapide",
+  "keyboard_shortcuts.home": "să deschidă fluxul Acasă",
+  "keyboard_shortcuts.hotkey": "Prescurtări",
+  "keyboard_shortcuts.legend": "să afișeze această legendă",
+  "keyboard_shortcuts.local": "să deschidă fluxul local",
+  "keyboard_shortcuts.mention": "să menționeze autorul",
+  "keyboard_shortcuts.muted": "să deschidă lista utilizatorilor opriți",
+  "keyboard_shortcuts.my_profile": "să deschidă profilul tău",
+  "keyboard_shortcuts.notifications": "să deschidă coloana cu notificări",
+  "keyboard_shortcuts.pinned": "să deschidă lista postărilor fixate",
+  "keyboard_shortcuts.profile": "să deschidă porfilul autorului",
+  "keyboard_shortcuts.reply": "să răspundă",
+  "keyboard_shortcuts.requests": "să deschidă lista cu cereri de urmărire",
+  "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.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",
+  "lists.account.add": "Adaugă în listă",
+  "lists.account.remove": "Elimină din listă",
+  "lists.delete": "Șterge lista",
+  "lists.edit": "Editează lista",
+  "lists.new.create": "Adaugă listă",
+  "lists.new.title_placeholder": "Titlu pentru noua listă",
+  "lists.search": "Caută printre persoanale pe care le urmărești",
+  "lists.subheading": "Listele tale",
+  "loading_indicator.label": "Încărcare...",
+  "media_gallery.toggle_visible": "Comutați vizibilitatea",
+  "missing_indicator.label": "Nu a fost găsit",
+  "missing_indicator.sublabel": "Această resursă nu a putut fi găsită",
+  "mute_modal.hide_notifications": "Ascunzi notificările de la acest utilizator?",
+  "navigation_bar.apps": "Aplicații mobile",
+  "navigation_bar.blocks": "Utilizatori blocați",
+  "navigation_bar.community_timeline": "Flux local",
+  "navigation_bar.compose": "Compune o nouă postare",
+  "navigation_bar.direct": "Mesaje directe",
+  "navigation_bar.discover": "Descoperă",
+  "navigation_bar.domain_blocks": "Domenii ascunse",
+  "navigation_bar.edit_profile": "Editează profilul",
+  "navigation_bar.favourites": "Favorite",
+  "navigation_bar.filters": "Cuvinte oprite",
+  "navigation_bar.follow_requests": "Cereri de urmărire",
+  "navigation_bar.info": "Despre această instanță",
+  "navigation_bar.keyboard_shortcuts": "Prescurtări",
+  "navigation_bar.lists": "Liste",
+  "navigation_bar.logout": "Deconectare",
+  "navigation_bar.mutes": "Utilizatori opriți",
+  "navigation_bar.personal": "Personal",
+  "navigation_bar.pins": "Postări fixate",
+  "navigation_bar.preferences": "Preferințe",
+  "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.reblog": "{name} a redistribuit postarea ta",
+  "notifications.clear": "Șterge notificările",
+  "notifications.clear_confirmation": "Ești sigur că vrei să ștergi toate notificările?",
+  "notifications.column_settings.alert": "Notificări pe desktop",
+  "notifications.column_settings.favourite": "Favorite:",
+  "notifications.column_settings.filter_bar.advanced": "Afișează toate categoriile",
+  "notifications.column_settings.filter_bar.category": "Bară de filtrare rapidă",
+  "notifications.column_settings.filter_bar.show": "Arată",
+  "notifications.column_settings.follow": "Noi urmăritori:",
+  "notifications.column_settings.mention": "Mențiuni:",
+  "notifications.column_settings.push": "Notificări push",
+  "notifications.column_settings.reblog": "Redistribuite:",
+  "notifications.column_settings.show": "Arată în coloană",
+  "notifications.column_settings.sound": "Redă sunet",
+  "notifications.filter.all": "Toate",
+  "notifications.filter.boosts": "Redistribuiri",
+  "notifications.filter.favourites": "Favorite",
+  "notifications.filter.follows": "Urmărește",
+  "notifications.filter.mentions": "Menționări",
+  "notifications.group": "{count} notificări",
+  "privacy.change": "Cine vede asta",
+  "privacy.direct.long": "Postează doar pentru utilizatorii menționați",
+  "privacy.direct.short": "Direct",
+  "privacy.private.long": "Postează doar pentru urmăritori",
+  "privacy.private.short": "Doar urmăritorii",
+  "privacy.public.long": "Postează în fluxul public",
+  "privacy.public.short": "Public",
+  "privacy.unlisted.long": "Nu afisa in fluxul public",
+  "privacy.unlisted.short": "Nelistat",
+  "regeneration_indicator.label": "Încărcare…",
+  "regeneration_indicator.sublabel": "Fluxul tău este în preparare!",
+  "relative_time.days": "{number}z",
+  "relative_time.hours": "{number}h",
+  "relative_time.just_now": "acum",
+  "relative_time.minutes": "{number}m",
+  "relative_time.seconds": "{number}s",
+  "reply_indicator.cancel": "Anulează",
+  "report.forward": "Redirecționează catre {target}",
+  "report.forward_hint": "Acest cont este de pe un alt server. Trimitem o copie anonimă a raportului și acolo?",
+  "report.hint": "Sesizarea va fi trimsă către moderatorii acestei instanțe. Poți oferi o explicație pentru această sesizare mai jos:",
+  "report.placeholder": "Comentarii opționale",
+  "report.submit": "Trimite",
+  "report.target": "Raportează {target}",
+  "search.placeholder": "Caută",
+  "search_popout.search_format": "Formate pentru căutare avansată",
+  "search_popout.tips.full_text": "Textele simple returnează statusuri pe care le-ai scris, favorizat, redistribuit, sau în care sunt menționate , deasmenea și utilizatorii sau hastagurile care se potrivesc.",
+  "search_popout.tips.hashtag": "hashtag",
+  "search_popout.tips.status": "status",
+  "search_popout.tips.text": "Textele simple returnează nume, nume de utilizarori și hastagurile care se potrivesc",
+  "search_popout.tips.user": "utilizator",
+  "search_results.accounts": "Oameni",
+  "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.delete": "Șterge",
+  "status.detailed_status": "Conversația detailată",
+  "status.direct": "Mesaj direct @{name}",
+  "status.embed": "ÃŽncorporare",
+  "status.favourite": "Favorite",
+  "status.filtered": "Sortate",
+  "status.load_more": "Încarcă mai multe",
+  "status.media_hidden": "Media ascunsă",
+  "status.mention": "Mentionează @{name}",
+  "status.more": "Mai mult",
+  "status.mute": "Oprește @{name}",
+  "status.mute_conversation": "Oprește conversația",
+  "status.open": "Extinde acest status",
+  "status.pin": "Fixează pe profil",
+  "status.pinned": "Postare fixată",
+  "status.read_more": "Citește mai mult",
+  "status.reblog": "Redistribuie",
+  "status.reblog_private": "Redistribuie către audiența originală",
+  "status.reblogged_by": "{name} a redistribuit",
+  "status.reblogs.empty": "Nimeni nu a redistribuit această postare până acum. Când cineva o va face, va apărea aici.",
+  "status.redraft": "Șterge și adaugă la ciorne",
+  "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",
+  "status.show_less_all": "Arată mai puțin pentru toți",
+  "status.show_more": "Arată mai mult",
+  "status.show_more_all": "Arată mai mult pentru toți",
+  "status.show_thread": "Arată topicul",
+  "status.unmute_conversation": "Repornește conversația",
+  "status.unpin": "Eliberează din profil",
+  "suggestions.dismiss": "Omite sugestia",
+  "suggestions.header": "Ai putea fi interesat de…",
+  "tabs_bar.federated_timeline": "Global",
+  "tabs_bar.home": "Acasă",
+  "tabs_bar.local_timeline": "Local",
+  "tabs_bar.notifications": "Notificări",
+  "tabs_bar.search": "Căutare",
+  "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_form.description": "Adaugă o descriere pentru persoanele cu deficiențe de vedere",
+  "upload_form.focus": "Schimbă previzualizarea",
+  "upload_form.undo": "Șterge",
+  "upload_progress.label": "Se Încarcă...",
+  "video.close": "ÃŽnchide video",
+  "video.exit_fullscreen": "ÃŽnchide",
+  "video.expand": "Extinde video",
+  "video.fullscreen": "Ecran întreg",
+  "video.hide": "Ascunde video",
+  "video.mute": "Oprește sonorul",
+  "video.pause": "Pauză",
+  "video.play": "Redare",
+  "video.unmute": "Repornește sunetul"
+}
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index ecde3fb2c07773cc5f617b34442d1f2d4f614d98..cb601089865c47fde78230d86cb292164bf5b611 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Бот",
   "account.block": "Блокировать",
   "account.block_domain": "Блокировать все с {domain}",
@@ -7,25 +8,31 @@
   "account.disclaimer_full": "Нижеуказанная информация может не полностью отражать профиль пользователя.",
   "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.media": "Медиаконтент",
+  "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": "Медиа",
   "account.mention": "Упомянуть",
   "account.moved_to": "Ищите {name} здесь:",
   "account.mute": "Заглушить",
   "account.mute_notifications": "Скрыть уведомления от @{name}",
   "account.muted": "Приглушён",
   "account.posts": "Посты",
-  "account.posts_with_replies": "Посты с ответами",
+  "account.posts_with_replies": "Посты и ответы",
   "account.report": "Пожаловаться",
   "account.requested": "Ожидает подтверждения",
   "account.share": "Поделиться профилем @{name}",
   "account.show_reblogs": "Показывать продвижения от @{name}",
   "account.unblock": "Разблокировать",
   "account.unblock_domain": "Разблокировать {domain}",
+  "account.unendorse": "Не рекомендовать в профиле",
   "account.unfollow": "Отписаться",
   "account.unmute": "Снять глушение",
   "account.unmute_notifications": "Показывать уведомления от @{name}",
@@ -59,9 +66,9 @@
   "column_header.show_settings": "Показать настройки",
   "column_header.unpin": "Открепить",
   "column_subheading.settings": "Настройки",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Только с медиа",
   "compose_form.direct_message_warning": "Этот статус будет виден только упомянутым пользователям.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "compose_form.direct_message_warning_learn_more": "Узнать больше",
   "compose_form.hashtag_warning": "Этот пост не будет показывается в поиске по хэштегу, т.к. он непубличный. Только публичные посты можно найти в поиске по хэштегу.",
   "compose_form.lock_disclaimer": "Ваш аккаунт не {locked}. Любой человек может подписаться на Вас и просматривать посты для подписчиков.",
   "compose_form.lock_disclaimer.lock": "закрыт",
@@ -72,7 +79,7 @@
   "compose_form.sensitive.unmarked": "Медиафайлы не отмечены как чувствительные",
   "compose_form.spoiler.marked": "Текст скрыт за предупреждением",
   "compose_form.spoiler.unmarked": "Текст не скрыт",
-  "compose_form.spoiler_placeholder": "Напишите свое предупреждение здесь",
+  "compose_form.spoiler_placeholder": "Текст предупреждения",
   "confirmation_modal.cancel": "Отмена",
   "confirmations.block.confirm": "Заблокировать",
   "confirmations.block.message": "Вы уверены, что хотите заблокировать {name}?",
@@ -84,8 +91,10 @@
   "confirmations.domain_block.message": "Вы на самом деле уверены, что хотите блокировать весь {domain}? В большинстве случаев нескольких отдельных блокировок или глушений достаточно.",
   "confirmations.mute.confirm": "Заглушить",
   "confirmations.mute.message": "Вы уверены, что хотите заглушить {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.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.unfollow.confirm": "Отписаться",
   "confirmations.unfollow.message": "Вы уверены, что хотите отписаться от {name}?",
   "embed.instructions": "Встройте этот статус на Вашем сайте, скопировав код внизу.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Результаты поиска",
   "emoji_button.symbols": "Символы",
   "emoji_button.travel": "Путешествия",
+  "empty_column.account_timeline": "No toots here!",
+  "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": "Developers",
-  "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.developers": "Для разработчиков",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Документация",
   "getting_started.heading": "Добро пожаловать",
-  "getting_started.invite": "Invite people",
-  "getting_started.open_source_notice": "Mastodon - программа с открытым исходным кодом. Вы можете помочь проекту или сообщить о проблемах на GitHub по адресу {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
+  "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",
   "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": "фокус на одном из столбцов",
   "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.toot": "начать писать новый пост",
   "keyboard_shortcuts.unfocus": "убрать фокус с поля ввода/поиска",
@@ -159,25 +213,27 @@
   "missing_indicator.label": "Не найдено",
   "missing_indicator.sublabel": "Запрашиваемый ресурс не найден",
   "mute_modal.hide_notifications": "Убрать уведомления от этого пользователя?",
+  "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Список блокировки",
   "navigation_bar.community_timeline": "Локальная лента",
+  "navigation_bar.compose": "Создать новый статус",
   "navigation_bar.direct": "Личные сообщения",
-  "navigation_bar.discover": "Discover",
+  "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.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.public_timeline": "Глобальная лента",
-  "navigation_bar.security": "Security",
+  "navigation_bar.security": "Безопасность",
   "notification.favourite": "{name} понравился Ваш статус",
   "notification.follow": "{name} подписался(-лась) на Вас",
   "notification.mention": "{name} упомянул(а) Вас",
@@ -186,35 +242,21 @@
   "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.push": "Push-уведомления",
-  "notifications.column_settings.push_meta": "Это устройство",
   "notifications.column_settings.reblog": "Продвижения:",
   "notifications.column_settings.show": "Показывать в колонке",
   "notifications.column_settings.sound": "Проигрывать звук",
-  "notifications.group": "{count} notifications",
-  "onboarding.done": "Готово",
-  "onboarding.next": "Далее",
-  "onboarding.page_five.public_timelines": "Локальная лента показывает публичные посты всех пользователей {domain}. Глобальная лента показывает публичные посты всех людей, на которых подписаны пользователи {domain}. Это - публичные ленты, отличный способ найти новые знакомства.",
-  "onboarding.page_four.home": "Домашняя лента показывает посты от тех, на кого Вы подписаны.",
-  "onboarding.page_four.notifications": "Колонка уведомлений сообщает о взаимодействии с Вами других людей.",
-  "onboarding.page_one.federation": "Mastodon - это сеть независимых серверов, которые вместе образуют единую социальную сеть. Мы называем эти сервера узлами.",
-  "onboarding.page_one.full_handle": "Всё в ваших руках",
-  "onboarding.page_one.handle_hint": "Это то, что вы посоветуете искать своим друзьям.",
-  "onboarding.page_one.welcome": "Добро пожаловать в Mastodon!",
-  "onboarding.page_six.admin": "Админ Вашего узла - {admin}.",
-  "onboarding.page_six.almost_done": "Почти готово...",
-  "onboarding.page_six.appetoot": "Удачи!",
-  "onboarding.page_six.apps_available": "Для взаимодействия с Mastodon существуют {apps} для iOS, Android и других платформ.",
-  "onboarding.page_six.github": "Mastodon - свободная программа с открытым исходным кодом. Вы можете сообщить о баге, предложить идею или поучаствовать в разработке на {github}.",
-  "onboarding.page_six.guidelines": "правила поведения",
-  "onboarding.page_six.read_guidelines": "Пожалуйста, прочитайте {guidelines} для {domain}!",
-  "onboarding.page_six.various_app": "мобильные приложения",
-  "onboarding.page_three.profile": "Отредактируйте свой профиль, чтобы изменить аватар, короткую информацию о Вас, отображаемое имя и другие настройки.",
-  "onboarding.page_three.search": "Используйте панель поиска, чтобы искать людей и хэштеги, например, {illustration} и {introductions}. Чтобы найти человека, находящегося на другом узле, введите его полное имя пользователя.",
-  "onboarding.page_two.compose": "Пишите посты в колонке автора. Вы можете загружать изображения, изменять настройки видимости и добавлять предупреждения о контенте с помощью иконок внизу.",
-  "onboarding.skip": "Пропустить",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.group": "{count} уведомл.",
   "privacy.change": "Изменить видимость статуса",
   "privacy.direct.long": "Показать только упомянутым",
   "privacy.direct.short": "Направленный",
@@ -250,29 +292,34 @@
   "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.block": "Заблокировать @{name}",
   "status.cancel_reblog_private": "Не продвигать",
   "status.cannot_reblog": "Этот статус не может быть продвинут",
   "status.delete": "Удалить",
+  "status.detailed_status": "Подробный просмотр обсуждения",
   "status.direct": "Написать @{name}",
   "status.embed": "Встроить",
   "status.favourite": "Нравится",
-  "status.filtered": "Filtered",
+  "status.filtered": "Отфильтровано",
   "status.load_more": "Показать еще",
-  "status.media_hidden": "Медиаконтент скрыт",
+  "status.media_hidden": "Медиа скрыто",
   "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.reblog": "Продвинуть",
   "status.reblog_private": "Продвинуть для своей аудитории",
   "status.reblogged_by": "{name} продвинул(а)",
-  "status.redraft": "Delete & re-draft",
+  "status.reblogs.empty": "Никто ещё не продвинул этот статус. Как только кто-то это сделает, они появятся здесь.",
+  "status.redraft": "Удалить и исправить",
   "status.reply": "Ответить",
-  "status.replyAll": "Ответить на тред",
+  "status.replyAll": "Ответить всем",
   "status.report": "Пожаловаться",
   "status.sensitive_toggle": "Нажмите для просмотра",
   "status.sensitive_warning": "Чувствительный контент",
@@ -281,14 +328,17 @@
   "status.show_less_all": "Свернуть для всех",
   "status.show_more": "Развернуть",
   "status.show_more_all": "Развернуть для всех",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Снять глушение с треда",
   "status.unpin": "Открепить от профиля",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Глобальная",
   "tabs_bar.home": "Главная",
   "tabs_bar.local_timeline": "Локальная",
   "tabs_bar.notifications": "Уведомления",
   "tabs_bar.search": "Поиск",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.count_by_accounts": "Популярно у {count} {rawCount, plural, one {человека} few {человек} many {человек} other {человек}}",
   "ui.beforeunload": "Ваш черновик будет утерян, если вы покинете Mastodon.",
   "upload_area.title": "Перетащите сюда, чтобы загрузить",
   "upload_button.label": "Добавить медиаконтент",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 47271f98ff116ce047f4a7a40101ae72ed428219..a3467785a434af2e084ef62365ac6718c23615ca 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Pridaj, alebo odstráň zo zoznamov",
   "account.badges.bot": "Bot",
   "account.block": "Blokuj @{name}",
   "account.block_domain": "Ukry všetko z {domain}",
@@ -7,30 +8,36 @@
   "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.follow": "Následovať",
+  "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_you": "Následuje ťa",
   "account.hide_reblogs": "Skryť povýšenia 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.muted": "Utíšený/á",
-  "account.posts": "Hlášky",
-  "account.posts_with_replies": "Príspevky s odpoveďami",
+  "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.show_reblogs": "Ukáž povýšenia od @{name}",
-  "account.unblock": "Odblokovať @{name}",
-  "account.unblock_domain": "Prestať blokovať {domain}",
-  "account.unfollow": "Prestať nasledovať",
-  "account.unmute": "Prestať ignorovať @{name}",
-  "account.unmute_notifications": "Odtĺmiť notifikácie od @{name}",
+  "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",
-  "alert.unexpected.message": "Vyskytla sa neočakávaná chyba.",
+  "alert.unexpected.message": "Vyskytla sa nečakaná chyba.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Nabudúce môžeš kliknúť {combo} pre preskočenie",
   "bundle_column_error.body": "Pri načítaní tohto prvku nastala nejaká chyba.",
@@ -63,7 +70,7 @@
   "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 zamknutý. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
+  "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.lock": "zamknutý",
   "compose_form.placeholder": "Čo máš na mysli?",
   "compose_form.publish": "Pošli",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "Ignoruj",
   "confirmations.mute.message": "Naozaj chcete ignorovať {name}?",
   "confirmations.redraft.confirm": "Vyčistiť a prepísať",
-  "confirmations.redraft.message": "Si si istý/á, že chceš vymazať a prepísať tento príspevok? Stratíš všetky jeho nadobudnuté odpovede, povýšenia a obľúbenia.",
+  "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}?",
   "embed.instructions": "Umiestni kód uvedený nižšie pre pridanie tohto statusu na tvoju web stránku.",
@@ -104,41 +113,86 @@
   "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.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.",
+  "empty_column.domain_blocks": "Žiadne domény ešte niesú skryté.",
+  "empty_column.favourited_statuses": "Nemáš obľúbené ešte žiadne príspevky. Keď si nejaký obľúbiš, bude zobrazený práve tu.",
+  "empty_column.favourites": "Tento toot si ešte nikto neobľúbil. Ten kto si ho obľúbi, bude zobrazený tu.",
+  "empty_column.follow_requests": "Ešte nemáš žiadne požiadavky o následovanie. Keď nejaké dostaneš, budú tu zobrazené.",
   "empty_column.hashtag": "Pod týmto hashtagom sa ešte nič nenachádza.",
   "empty_column.home": "Tvoja lokálna osa je zatiaľ prázdna! Pre začiatok navštív {public}, alebo použi vyhľadávanie a nájdi tak aj iných užívateľov.",
   "empty_column.home.public_timeline": "verejná časová os",
   "empty_column.list": "Tento zoznam je ešte prázdny. Keď ale členovia tohoto zoznamu napíšu nové správy, tak tie sa objavia priamo tu.",
-  "empty_column.notifications": "Nemáš ešte žiadne oznámenia. Zapoj sa s niekym do debaty a komunikuj s ostatnými aby diskusia mohla začať.",
-  "empty_column.public": "Ešte tu nič nie je. Napíš niečo verejne alebo začnite sledovať užívateľov z iných Mastodon serverov, aby tu tak niečo pribudlo",
+  "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",
   "follow_request.authorize": "Povoľ prístup",
   "follow_request.reject": "Odmietni",
   "getting_started.developers": "Vývojári",
+  "getting_started.directory": "Databáza profilov",
   "getting_started.documentation": "Dokumentácia",
-  "getting_started.find_friends": "Nájdi priateľov z Twitteru",
   "getting_started.heading": "Začni tu",
   "getting_started.invite": "Pozvať ľudí",
   "getting_started.open_source_notice": "Mastodon je softvér s otvoreným kódom. Nahlásiť chyby, alebo prispievať môžeš na GitHube v {github}.",
   "getting_started.security": "Zabezpečenie",
   "getting_started.terms": "Podmienky prevozu",
+  "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.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",
   "home.column_settings.basic": "Základné",
   "home.column_settings.show_reblogs": "Zobraziť povýšené",
   "home.column_settings.show_replies": "Ukázať odpovede",
+  "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.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.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.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.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.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.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.local": "otvor miestnu časovú os",
   "keyboard_shortcuts.mention": "spomenúť 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.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",
@@ -149,24 +203,26 @@
   "lists.account.add": "Pridať do zoznamu",
   "lists.account.remove": "Odobrať zo zoznamu",
   "lists.delete": "Vymazať list",
-  "lists.edit": "Upraviť zoznam",
-  "lists.new.create": "Pridať zoznam",
+  "lists.edit": "Uprav zoznam",
+  "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.subheading": "Tvoje zoznamy",
   "loading_indicator.label": "Načítam...",
   "media_gallery.toggle_visible": "Zapnúť/Vypnúť viditeľnosť",
   "missing_indicator.label": "Nenájdené",
-  "missing_indicator.sublabel": "Tento zdroj sa nepodarilo nájsť",
-  "mute_modal.hide_notifications": "Skryť notifikácie od tohoto užívateľa?",
+  "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",
   "navigation_bar.blocks": "Blokovaní užívatelia",
   "navigation_bar.community_timeline": "Lokálna č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": "Upraviť profil",
+  "navigation_bar.edit_profile": "Uprav profil",
   "navigation_bar.favourites": "Obľúbené",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Utĺmené slová",
   "navigation_bar.follow_requests": "Žiadosti o sledovanie",
   "navigation_bar.info": "O tomto Mastodon serveri",
   "navigation_bar.keyboard_shortcuts": "Klávesové skratky",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Naozaj chcete nenávratne prečistiť všetky vaše notifikácie?",
   "notifications.column_settings.alert": "Notifikácie na ploche",
   "notifications.column_settings.favourite": "Obľúbené:",
+  "notifications.column_settings.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.mention": "Zmienenia:",
   "notifications.column_settings.push": "Push notifikácie",
-  "notifications.column_settings.push_meta": "Toto zariadenie",
   "notifications.column_settings.reblog": "Boosty:",
   "notifications.column_settings.show": "Zobraziť v stĺpci",
   "notifications.column_settings.sound": "Prehrať 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",
-  "onboarding.done": "Koniec",
-  "onboarding.next": "ÄŽalej",
-  "onboarding.page_five.public_timelines": "Lokálna časová os zobrazuje verejné správy od všetkých na {domain}. Federovaná časová os zobrazuje verejné správy od všetkých tých, čo následujú užívatrľov {domain} z iných serverov. Tieto sú takzvané Verejné Časové Osi, výborná možnosť ako nájsť a spoznať nových ľudí.",
-  "onboarding.page_four.home": "Domovská časová os zobrazí správy od ľudí ktorých sledujete.",
-  "onboarding.page_four.notifications": "Stĺpec s notifikáciami zobrazí keď budete s niekým komunikovať.",
-  "onboarding.page_one.federation": "Mastodon je sieť nezávislých serverov, spojením ktorých vzniká jedna veľká federovaná sociálna sieť.",
-  "onboarding.page_one.full_handle": "Vaša celá prezývka aj s adresou",
-  "onboarding.page_one.handle_hint": "Toto je čo by si povedal/a vaším kamarátom, že majú hľadať.",
-  "onboarding.page_one.welcome": "Vitaj na Mastodone!",
-  "onboarding.page_six.admin": "Správcom tvojej instancie je {admin}.",
-  "onboarding.page_six.almost_done": "Takmer hotovo...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Aplikácie {apps} sú dostupné na pre iOS, Android and ďalšie platformy.",
-  "onboarding.page_six.github": "Mastodon je free open-source software. Nahlásiť chyby, zaujímať sa o nové funkcie, alebo prispievať svojím kódom mǒžeete na {github}.",
-  "onboarding.page_six.guidelines": "pravidlá komunity",
-  "onboarding.page_six.read_guidelines": "Prosím prečítajte si {domain} pravidlá {guidelines}!",
-  "onboarding.page_six.various_app": "mobilné applikácie",
-  "onboarding.page_three.profile": "Upravte svoj profil ak chcete zmeňiť svoj avatar, popis profilu a meno ktoré bude zobrazené. V nastaveniach nájdete ďalšie možnosti.",
-  "onboarding.page_three.search": "Použite vyhľadávacie políčko na nájdenie ľudí a hashtagov, ako napríklad {slovensko}, {slovakia} alebo {pivo}. Na nájdenie človeka ktorý je registrovaný na inom Mastodon serveri použi jeho celý nickname.",
-  "onboarding.page_two.compose": "Správy píšte zo stĺpca na komponovanie. Je možné nahrávať obrázky, meniť nastavenia súkromia správ a pridávať varovania ikonkami nižšie.",
-  "onboarding.skip": "Preskočiť",
   "privacy.change": "Zmeňiť viditeľnosť statusu",
   "privacy.direct.long": "Poslať priamo iba spomenutým používateľom",
   "privacy.direct.short": "Súkromne",
@@ -248,16 +290,19 @@
   "search_results.accounts": "Ľudia",
   "search_results.hashtags": "Haštagy",
   "search_results.statuses": "Príspevky",
-  "search_results.total": "{count, number} {count, plural, jeden {výsledok} ostatné {výsledky}}",
+  "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.cancel_reblog_private": "Nezdieľaj",
   "status.cannot_reblog": "Tento príspevok nemôže byť re-tootnutý",
   "status.delete": "Zmazať",
+  "status.detailed_status": "Podrobný náhľad celej konverzácie",
   "status.direct": "Súkromná správa @{name}",
   "status.embed": "Vložiť",
   "status.favourite": "Páči sa mi",
-  "status.filtered": "Filtered",
+  "status.filtered": "Filtrované",
   "status.load_more": "Ukáž viac",
   "status.media_hidden": "Skryté médiá",
   "status.mention": "Spomeň @{name}",
@@ -267,33 +312,38 @@
   "status.open": "Otvoriť tento status",
   "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.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.redraft": "Vymaž a prepíš",
   "status.reply": "Odpovedať",
   "status.replyAll": "Odpovedať na diskusiu",
   "status.report": "Nahlásiť @{name}",
-  "status.sensitive_toggle": "Kliknite pre zobrazenie",
+  "status.sensitive_toggle": "Klikni pre zobrazenie",
   "status.sensitive_warning": "Chúlostivý obsah",
   "status.share": "Zdieľať",
   "status.show_less": "Zobraz menej",
   "status.show_less_all": "Všetkým ukáž menej",
   "status.show_more": "Ukáž viac",
   "status.show_more_all": "Všetkým ukáž viac",
-  "status.unmute_conversation": "Prestať ignorovať konverzáciu",
-  "status.unpin": "Odopnúť z profilu",
+  "status.show_thread": "Ukáž diskusné vlákno",
+  "status.unmute_conversation": "Prestaň ignorovať konverzáciu",
+  "status.unpin": "Odopni z profilu",
+  "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.search": "Hľadaj",
-  "trends.count_by_accounts": "{count} {rawCount, viacerí, jeden {person} iní {people}} diskutujú",
+  "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á",
+  "upload_button.label": "Pridať médiálny súbor (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "Opis pre slabo vidiacich",
-  "upload_form.focus": "Vystrihni",
+  "upload_form.focus": "Pozmeň náhľad",
   "upload_form.undo": "Vymaž",
   "upload_progress.label": "Nahráva sa...",
   "video.close": "Zavrieť video",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index 73f31e8cf8c58e82b36bee596a7043acfb7e7130..cabad737d65871292ed0e92032a208c08f6377d6 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Robot",
   "account.block": "Blokiraj @{name}",
   "account.block_domain": "Skrij vse iz {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Sledi",
   "account.followers": "Sledilci",
+  "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 napuhke od @{name}",
+  "account.hide_reblogs": "Skrij sunke 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.media": "Mediji",
   "account.mention": "Omeni @{name}",
   "account.moved_to": "{name} se je premaknil na:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Pokaži delitve osebe @{name}",
   "account.unblock": "Odblokiraj @{name}",
   "account.unblock_domain": "Razkrij {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Prenehaj slediti",
   "account.unmute": "Odtišaj @{name}",
   "account.unmute_notifications": "Vklopi obvestila od @{name}",
@@ -59,9 +66,9 @@
   "column_header.show_settings": "Prikaži nastavitve",
   "column_header.unpin": "Odpni",
   "column_subheading.settings": "Nastavitve",
-  "community.column_settings.media_only": "Media Only",
+  "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": "Learn more",
+  "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.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",
@@ -84,8 +91,10 @@
   "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.mute.confirm": "Utišanje",
   "confirmations.mute.message": "Ali ste prepričani, da želite utišati {name}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
+  "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.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.",
@@ -104,41 +113,86 @@
   "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.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.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.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.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",
   "follow_request.reject": "Zavrni",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "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",
   "home.column_settings.basic": "Osnovno",
   "home.column_settings.show_reblogs": "Pokaži sunke",
   "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",
   "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.heading": "Tipkovne bližnjice",
+  "keyboard_shortcuts.home": "to open home timeline",
   "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",
@@ -159,8 +213,10 @@
   "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",
@@ -186,35 +242,21 @@
   "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.push_meta": "This device",
   "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",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetut!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
-  "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -250,10 +292,13 @@
   "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",
@@ -267,9 +312,11 @@
   "status.open": "Expand this status",
   "status.pin": "Pin on profile",
   "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.reply": "Odgovori",
   "status.replyAll": "Odgovori na objavo",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Prikaži manj za vse",
   "status.show_more": "Prikaži več",
   "status.show_more_all": "Prikaži več za vse",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Odtišaj pogovor",
   "status.unpin": "Odpni iz profila",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Združeno",
   "tabs_bar.home": "Domov",
   "tabs_bar.local_timeline": "Lokalno",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index e3bf2189b448950899656cf2c7b5d3d3a479a484..c8513dbe1809c75cbb002d186e6500051fd27bf1 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Blokiraj korisnika @{name}",
   "account.block_domain": "Sakrij sve sa domena {domain}",
@@ -7,11 +8,16 @@
   "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",
   "account.follow": "Zaprati",
   "account.followers": "Pratioca",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Prati",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Prati Vas",
   "account.hide_reblogs": "Sakrij podrške koje daje korisnika @{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": "Mediji",
   "account.mention": "Pomeni korisnika @{name}",
   "account.moved_to": "{name} se pomerio na:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Prikaži podrške od korisnika @{name}",
   "account.unblock": "Odblokiraj korisnika @{name}",
   "account.unblock_domain": "Odblokiraj domen {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Otprati",
   "account.unmute": "Ukloni ućutkavanje korisniku @{name}",
   "account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}",
@@ -86,6 +93,8 @@
   "confirmations.mute.message": "Da li stvarno želite da ućutkate korisnika {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": "Otprati",
   "confirmations.unfollow.message": "Da li ste sigurni da želite da otpratite korisnika {name}?",
   "embed.instructions": "Ugradi ovaj status na Vaš veb sajt kopiranjem koda ispod.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Rezultati pretrage",
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Putovanja & mesta",
+  "empty_column.account_timeline": "No toots here!",
+  "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.",
+  "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": "Trenutno nema ništa na ovom heštegu.",
   "empty_column.home": "Vaša lajna je prazna! Posetite {public} ili koristite pretragu da počnete i upoznajete nove ljude.",
   "empty_column.home.public_timeline": "javna lajna",
   "empty_column.list": "U ovoj listi još nema ničega. Kada članovi liste objave nove statuse, oni će se pojavljivati ovde.",
+  "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": "Trenutno nemate obaveštenja. Družite se malo da započnete razgovore.",
   "empty_column.public": "Ovde nema ničega! Napišite nešto javno, ili nađite korisnike sa drugih instanci koje ćete zapratiti da popunite ovu prazninu",
   "follow_request.authorize": "Odobri",
   "follow_request.reject": "Odbij",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Da počnete",
   "getting_started.invite": "Invite people",
   "getting_started.open_source_notice": "Mastodont je softver otvorenog koda. Možete mu doprineti ili prijaviti probleme preko GitHub-a na {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": "Osnovno",
   "home.column_settings.show_reblogs": "Prikaži i podržavanja",
   "home.column_settings.show_replies": "Prikaž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": "da odete nazad",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
   "keyboard_shortcuts.boost": "da podržite",
   "keyboard_shortcuts.column": "da se prebacite na status u jednoj od kolona",
   "keyboard_shortcuts.compose": "da se prebacite na pisanje novog tuta",
   "keyboard_shortcuts.description": "Opis",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "keyboard_shortcuts.down": "da se pomerite na dole u listi",
   "keyboard_shortcuts.enter": "da otvorite status",
   "keyboard_shortcuts.favourite": "da označite kao omiljeno",
+  "keyboard_shortcuts.favourites": "to open favourites list",
+  "keyboard_shortcuts.federated": "to open federated timeline",
   "keyboard_shortcuts.heading": "Prečice na tastaturi",
+  "keyboard_shortcuts.home": "to open home timeline",
   "keyboard_shortcuts.hotkey": "Prečica",
   "keyboard_shortcuts.legend": "da prikažete ovaj podsetnik",
+  "keyboard_shortcuts.local": "to open local timeline",
   "keyboard_shortcuts.mention": "da pomenete autora",
+  "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": "da odgovorite",
+  "keyboard_shortcuts.requests": "to open follow requests list",
   "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.toot": "da započnete skroz novi tut",
   "keyboard_shortcuts.unfocus": "da ne budete više na pretrazi/pravljenju novog tuta",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "Nije pronađeno",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Sakrij obaveštenja od ovog korisnika?",
+  "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokirani korisnici",
   "navigation_bar.community_timeline": "Lokalna lajna",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Da li ste sigurno da trajno želite da očistite Vaša obaveštenja?",
   "notifications.column_settings.alert": "Obaveštenja na radnoj površini",
   "notifications.column_settings.favourite": "Omiljeni:",
+  "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": "Novi pratioci:",
   "notifications.column_settings.mention": "Pominjanja:",
   "notifications.column_settings.push": "Guraj obaveštenja",
-  "notifications.column_settings.push_meta": "Ovaj uređaj",
   "notifications.column_settings.reblog": "Podrški:",
   "notifications.column_settings.show": "Prikaži u koloni",
   "notifications.column_settings.sound": "Puštaj zvuk",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifications",
-  "onboarding.done": "Gotovo",
-  "onboarding.next": "Sledeće",
-  "onboarding.page_five.public_timelines": "Lokalna lajna prikazuje sve javne statuse od svih na domenu {domain}. Federisana lajna prikazuje javne statuse od svih ljudi koje prate korisnici sa domena {domain}. Ovo su javne lajne, sjajan način da otkrijete nove ljude.",
-  "onboarding.page_four.home": "Početna lajna prikazuje statuse ljudi koje Vi pratite.",
-  "onboarding.page_four.notifications": "Kolona sa obaveštenjima Vam prikazuje kada neko priča sa Vama.",
-  "onboarding.page_one.federation": "Mastodont je mreža nezavisnih servera koji se uvezuju da naprave jednu veću društvenu mrežu. Ove servere zovemo instancama.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Dobrodošli na Mastodont!",
-  "onboarding.page_six.admin": "Administrator Vaše instance je {admin}.",
-  "onboarding.page_six.almost_done": "Još malo, pa gotovo...",
-  "onboarding.page_six.appetoot": "Prijatutno!",
-  "onboarding.page_six.apps_available": "Postoje {apps} dostupne za iOS, Android i druge platforme.",
-  "onboarding.page_six.github": "Mastodont je slobodan softver otvorenog koda. Možete prijavljivati greške, potraživati nove funckionalnosti, ili učestvujući u programiranju. Naš izvorni kod je ovde: {github}.",
-  "onboarding.page_six.guidelines": "smernice zajednice",
-  "onboarding.page_six.read_guidelines": "Pročitejte {guidelines} domena {domain}!",
-  "onboarding.page_six.various_app": "mobilne aplikacije",
-  "onboarding.page_three.profile": "Izmenite profil da promenite avatar, biografiju i ime za prikaz. Tamo ćete naći i ostala podešavanja.",
-  "onboarding.page_three.search": "Korisite pretragu da nađete ljude i gledate heštegove, kao što su {illustration} i {introductions}. Da nađete osobu koja nije na ovoj instanci, koristite njenu punu identifikaciju.",
-  "onboarding.page_two.compose": "Pišite statuse iz prve kolone. Možete otpremati slike, menjati podešavanja privatnosti, i dodavati upozorenja za osetljiv sadržaj preko ikonica ispod.",
-  "onboarding.skip": "Preskoči",
   "privacy.change": "Podesi status privatnosti",
   "privacy.direct.long": "Objavi samo korisnicima koji su pomenuti",
   "privacy.direct.short": "Direktno",
@@ -250,10 +292,13 @@
   "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.delete": "Obriši",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Ugradi na sajt",
   "status.favourite": "Omiljeno",
@@ -267,9 +312,11 @@
   "status.open": "Proširi ovaj status",
   "status.pin": "Prikači na profil",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "Podrži",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "{name} podržao(la)",
+  "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": "Odgovori",
   "status.replyAll": "Odgovori na diskusiju",
@@ -281,8 +328,11 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Prikaži više",
   "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Uključi prepisku",
   "status.unpin": "Otkači sa profila",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Federisano",
   "tabs_bar.home": "Početna",
   "tabs_bar.local_timeline": "Lokalno",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index ba84a4d24e73685caaa25cd6818f52a989771f87..6e0ac6eca7c3f1b9d398feff379d20fc3d9cd185 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -1,37 +1,44 @@
 {
-  "account.badges.bot": "Bot",
-  "account.block": "Блокирај корисника @{name}",
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.badges.bot": "Бот",
+  "account.block": "Блокирај @{name}",
   "account.block_domain": "Сакриј све са домена {domain}",
-  "account.blocked": "Blocked",
-  "account.direct": "Direct Message @{name}",
+  "account.blocked": "Блокиран",
+  "account.direct": "Директна порука @{name}",
   "account.disclaimer_full": "Наведене информације можда не одсликавају кориснички профил у потпуности.",
-  "account.domain_blocked": "Domain hidden",
+  "account.domain_blocked": "Домен сакривен",
   "account.edit_profile": "Измени профил",
+  "account.endorse": "Приказати на профилу",
   "account.follow": "Запрати",
-  "account.followers": "Пратиоца",
+  "account.followers": "Пратиоци",
+  "account.followers.empty": "Тренутно нико не прати овог корисника.",
   "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.media": "Медији",
   "account.mention": "Помени корисника @{name}",
   "account.moved_to": "{name} се померио на:",
   "account.mute": "Ућуткај корисника @{name}",
   "account.mute_notifications": "Искључи обавештења од корисника @{name}",
-  "account.muted": "Muted",
-  "account.posts": "Статуса",
-  "account.posts_with_replies": "Toots with replies",
+  "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}",
   "account.view_full_profile": "Види цео профил",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
+  "alert.unexpected.message": "Појавила се неочекивана грешка.",
+  "alert.unexpected.title": "Упс!",
   "boost_modal.combo": "Можете притиснути {combo} да прескочите ово следећи пут",
   "bundle_column_error.body": "Нешто је пошло по злу приликом учитавања ове компоненте.",
   "bundle_column_error.retry": "Покушајте поново",
@@ -40,17 +47,17 @@
   "bundle_modal_error.message": "Нешто није било у реду при учитавању ове компоненте.",
   "bundle_modal_error.retry": "Покушајте поново",
   "column.blocks": "Блокирани корисници",
-  "column.community": "Локална лајна",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
-  "column.favourites": "Омиљени",
+  "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.pins": "Прикачене трубе",
+  "column.public": "Здружена временска линија",
   "column_back_button.label": "Назад",
   "column_header.hide_settings": "Сакриј поставке",
   "column_header.moveLeft_settings": "Помери колону улево",
@@ -59,19 +66,19 @@
   "column_header.show_settings": "Прикажи поставке",
   "column_header.unpin": "Откачи",
   "column_subheading.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.",
+  "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.publish": "Тутни",
+  "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.sensitive.marked": "Медији су означени као осетљиви",
+  "compose_form.sensitive.unmarked": "Медији су означени као не-осетљиви",
+  "compose_form.spoiler.marked": "Текст је сакривен иза упозорења",
+  "compose_form.spoiler.unmarked": "Текст није сакривен",
   "compose_form.spoiler_placeholder": "Овде упишите упозорење",
   "confirmation_modal.cancel": "Поништи",
   "confirmations.block.confirm": "Блокирај",
@@ -81,11 +88,13 @@
   "confirmations.delete_list.confirm": "Обриши",
   "confirmations.delete_list.message": "Да ли сте сигурни да желите да бесповратно обришете ову листу?",
   "confirmations.domain_block.confirm": "Сакриј цео домен",
-  "confirmations.domain_block.message": "Да ли сте стварно, стварно сигурно да желите да блокирате цео домен {domain}? У већини случајева, пар добрих блокирања или ућуткавања су довољна и препоручљива.",
+  "confirmations.domain_block.message": "Да ли сте заиста сигурни да желите да блокирате цео домен {domain}? У већини случајева, неколико добро промишљених блокирања или ућуткавања су довољна и препоручљива.",
   "confirmations.mute.confirm": "Ућуткај",
   "confirmations.mute.message": "Да ли стварно желите да ућуткате корисника {name}?",
-  "confirmations.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.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.unfollow.confirm": "Отпрати",
   "confirmations.unfollow.message": "Да ли сте сигурни да желите да отпратите корисника {name}?",
   "embed.instructions": "Угради овај статус на Ваш веб сајт копирањем кода испод.",
@@ -93,55 +102,100 @@
   "emoji_button.activity": "Активност",
   "emoji_button.custom": "Произвољно",
   "emoji_button.flags": "Заставе",
-  "emoji_button.food": "Храна & пиће",
-  "emoji_button.label": "Убаци смајли",
+  "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.search": "Претрага...",
   "emoji_button.search_results": "Резултати претраге",
   "emoji_button.symbols": "Симболи",
-  "emoji_button.travel": "Путовања & места",
-  "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.",
-  "empty_column.hashtag": "Тренутно нема ништа на овом хештегу.",
-  "empty_column.home": "Ваша лајна је празна! Посетите {public} или користите претрагу да почнете и упознајете нове људе.",
-  "empty_column.home.public_timeline": "јавна лајна",
-  "empty_column.list": "У овој листи још нема ничега. Када чланови листе објаве нове статусе, они ће се појављивати овде.",
-  "empty_column.notifications": "Тренутно немате обавештења. Дружите се мало да започнете разговоре.",
+  "emoji_button.travel": "Путовања и места",
+  "empty_column.account_timeline": "No toots here!",
+  "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": "Developers",
-  "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.developers": "Програмери",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Документација",
   "getting_started.heading": "Да почнете",
-  "getting_started.invite": "Invite people",
-  "getting_started.open_source_notice": "Мастoдонт је софтвер отвореног кода. Можете му допринети или пријавити проблеме преко GitHub-а на {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
+  "getting_started.invite": "Позовите људе",
+  "getting_started.open_source_notice": "Мастoдон је софтвер отвореног кода. Можете му допринети или пријавити проблеме преко ГитХаба на {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",
   "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": "да се пребаците на статус у једној од колона",
   "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.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "да започнете скроз нови тут",
-  "keyboard_shortcuts.unfocus": "да не будете више на претрази/прављењу новог тута",
+  "keyboard_shortcuts.start": "да отворите колону \"почнимо\"",
+  "keyboard_shortcuts.toggle_hidden": "да прикажете/сакријте текст иза CW-а",
+  "keyboard_shortcuts.toot": "да започнете скроз нову трубу",
+  "keyboard_shortcuts.unfocus": "да одфокусирате/не будете више на претрази/прављењу нове трубе",
   "keyboard_shortcuts.up": "да се померите на горе у листи",
   "lightbox.close": "Затвори",
   "lightbox.next": "Следећи",
@@ -157,16 +211,18 @@
   "loading_indicator.label": "Учитавам...",
   "media_gallery.toggle_visible": "Укључи/искључи видљивост",
   "missing_indicator.label": "Није пронађено",
-  "missing_indicator.sublabel": "This resource could not be found",
+  "missing_indicator.sublabel": "Овај ресурс није пронађен",
   "mute_modal.hide_notifications": "Сакриј обавештења од овог корисника?",
+  "navigation_bar.apps": "Мобилне апликације",
   "navigation_bar.blocks": "Блокирани корисници",
-  "navigation_bar.community_timeline": "Локална лајна",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
+  "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": "Muted words",
+  "navigation_bar.favourites": "Омиљене",
+  "navigation_bar.filters": "Пригушене речи",
   "navigation_bar.follow_requests": "Захтеви за праћење",
   "navigation_bar.info": "О овој инстанци",
   "navigation_bar.keyboard_shortcuts": "Пречице на тастатури",
@@ -174,47 +230,33 @@
   "navigation_bar.logout": "Одјава",
   "navigation_bar.mutes": "Ућуткани корисници",
   "navigation_bar.personal": "Personal",
-  "navigation_bar.pins": "Прикачени тутови",
+  "navigation_bar.pins": "Прикачене трубе",
   "navigation_bar.preferences": "Подешавања",
-  "navigation_bar.public_timeline": "Федерисана лајна",
-  "navigation_bar.security": "Security",
-  "notification.favourite": "{name} је ставио Ваш статус као омиљени",
-  "notification.follow": "{name} Вас је запратио",
-  "notification.mention": "{name} Вас је поменуо",
-  "notification.reblog": "{name} је подржао(ла) Ваш статус",
+  "navigation_bar.public_timeline": "Здружена временска линија",
+  "navigation_bar.security": "Безбедност",
+  "notification.favourite": "{name} је ставио/ла Ваш статус као омиљени",
+  "notification.follow": "{name} Вас је запратио/ла",
+  "notification.mention": "{name} Вас је поменуо/ла",
+  "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.push": "Гурај обавештења",
-  "notifications.column_settings.push_meta": "Овај уређај",
   "notifications.column_settings.reblog": "Подршки:",
   "notifications.column_settings.show": "Прикажи у колони",
   "notifications.column_settings.sound": "Пуштај звук",
-  "notifications.group": "{count} notifications",
-  "onboarding.done": "Готово",
-  "onboarding.next": "Следеће",
-  "onboarding.page_five.public_timelines": "Локална лајна приказује све јавне статусе од свих на домену {domain}. Федерисана лајна приказује јавне статусе од свих људи које прате корисници са домена {domain}. Ово су јавне лајне, сјајан начин да откријете нове људе.",
-  "onboarding.page_four.home": "Почетна лајна приказује статусе људи које Ви пратите.",
-  "onboarding.page_four.notifications": "Колона са обавештењима Вам приказује када неко прича са Вама.",
-  "onboarding.page_one.federation": "Мастодонт је мрежа независних сервера који се увезују да направе једну већу друштвену мрежу. Ове сервере зовемо инстанцама.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Добродошли на Мастодонт!",
-  "onboarding.page_six.admin": "Администратор Ваше инстанце је {admin}.",
-  "onboarding.page_six.almost_done": "Још мало, па готово...",
-  "onboarding.page_six.appetoot": "Пријатутно!",
-  "onboarding.page_six.apps_available": "Постоје {apps} доступне за iOS, Андроид и друге платформе.",
-  "onboarding.page_six.github": "Мастодонт је слободан софтвер отвореног кода. Можете пријављивати грешке, потраживати нове фунцкионалности, или учествујући у програмирању. Наш изворни код је овде: {github}.",
-  "onboarding.page_six.guidelines": "смернице заједнице",
-  "onboarding.page_six.read_guidelines": "Прочитејте {guidelines} домена {domain}!",
-  "onboarding.page_six.various_app": "мобилне апликације",
-  "onboarding.page_three.profile": "Измените профил да промените аватар, биографију и име за приказ. Тамо ћете наћи и остала подешавања.",
-  "onboarding.page_three.search": "Корисите претрагу да нађете људе и гледате хештегове, као што су {illustration} и {introductions}. Да нађете особу која није на овој инстанци, користите њену пуну идентификацију.",
-  "onboarding.page_two.compose": "Пишите статусе из прве колоне. Можете отпремати слике, мењати подешавања приватности, и додавати упозорења за осетљив садржај преко иконица испод.",
-  "onboarding.skip": "Прескочи",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.group": "{count} обавештења",
   "privacy.change": "Подеси статус приватности",
   "privacy.direct.long": "Објави само корисницима који су поменути",
   "privacy.direct.short": "Директно",
@@ -222,55 +264,60 @@
   "privacy.private.short": "Само за пратиоце",
   "privacy.public.long": "Објави на јавној лајни",
   "privacy.public.short": "Јавно",
-  "privacy.unlisted.long": "Не објављуј на јавним лајнама",
+  "privacy.unlisted.long": "Не објављуј на јавним временским линијама",
   "privacy.unlisted.short": "Неизлистано",
-  "regeneration_indicator.label": "Loading…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "regeneration_indicator.label": "Учитавање…",
+  "regeneration_indicator.sublabel": "Ваша почетна страница се припрема!",
   "relative_time.days": "{number}d",
   "relative_time.hours": "{number}h",
   "relative_time.just_now": "сада",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Поништи",
-  "report.forward": "Forward to {target}",
-  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
-  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.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, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.tips.full_text": "Једноставан текст враћа статусе које сте написали, фаворизовали, подржали или били поменути, као и подударање корисничких имена, приказаних имена, и тараба.",
   "search_popout.tips.hashtag": "хештег",
   "search_popout.tips.status": "статус",
   "search_popout.tips.text": "Тражењем обичног текста ћете добити сва пронађена имена, сва корисничка имена и све нађене хештегове",
   "search_popout.tips.user": "корисник",
-  "search_results.accounts": "People",
-  "search_results.hashtags": "Hashtags",
-  "search_results.statuses": "Toots",
+  "search_results.accounts": "Људи",
+  "search_results.hashtags": "Тарабе",
+  "search_results.statuses": "Трубе",
   "search_results.total": "{count, number} {count, plural, one {резултат} few {резултата} other {резултата}}",
   "standalone.public_title": "Поглед изнутра...",
-  "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
+  "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.delete": "Обриши",
-  "status.direct": "Direct message @{name}",
+  "status.detailed_status": "Детаљни преглед разговора",
+  "status.direct": "Директна порука @{name}",
   "status.embed": "Угради на сајт",
   "status.favourite": "Омиљено",
-  "status.filtered": "Filtered",
+  "status.filtered": "Филтрирано",
   "status.load_more": "Учитај још",
   "status.media_hidden": "Мултимедија сакривена",
   "status.mention": "Помени корисника @{name}",
   "status.more": "Још",
-  "status.mute": "Mute @{name}",
+  "status.mute": "Ућуткај @{name}",
   "status.mute_conversation": "Ућуткај преписку",
   "status.open": "Прошири овај статус",
-  "status.pin": "Прикачи на профил",
-  "status.pinned": "Pinned toot",
+  "status.pin": "Закачи на профил",
+  "status.pinned": "Закачена труба",
+  "status.read_more": "Read more",
   "status.reblog": "Подржи",
-  "status.reblog_private": "Boost to original audience",
-  "status.reblogged_by": "{name} подржао(ла)",
-  "status.redraft": "Delete & re-draft",
+  "status.reblog_private": "Подржи да види првобитна публика",
+  "status.reblogged_by": "{name} подржао/ла",
+  "status.reblogs.empty": "Још увек нико није подржао ову трубу. Када буде подржана, појавиће се овде.",
+  "status.redraft": "Избриши и преправи",
   "status.reply": "Одговори",
   "status.replyAll": "Одговори на дискусију",
   "status.report": "Пријави корисника @{name}",
@@ -278,23 +325,26 @@
   "status.sensitive_warning": "Осетљив садржај",
   "status.share": "Подели",
   "status.show_less": "Прикажи мање",
-  "status.show_less_all": "Show less for all",
+  "status.show_less_all": "Прикажи мање за све",
   "status.show_more": "Прикажи више",
-  "status.show_more_all": "Show more for all",
+  "status.show_more_all": "Прикажи више за све",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Укључи преписку",
   "status.unpin": "Откачи са профила",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Федерисано",
   "tabs_bar.home": "Почетна",
   "tabs_bar.local_timeline": "Локално",
   "tabs_bar.notifications": "Обавештења",
-  "tabs_bar.search": "Search",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "tabs_bar.search": "Претрага",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {човек} other {људи}} прича",
   "ui.beforeunload": "Ако напустите Мастодонт, изгубићете написани нацрт.",
   "upload_area.title": "Превуците овде да отпремите",
-  "upload_button.label": "Додај мултимедију",
-  "upload_form.description": "Опиши за слабовиде особе",
-  "upload_form.focus": "Crop",
-  "upload_form.undo": "Опозови",
+  "upload_button.label": "Додај мултимедију (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_form.description": "Опишите за особе са оштећеним видом",
+  "upload_form.focus": "Подесите",
+  "upload_form.undo": "Обриши",
   "upload_progress.label": "Отпремам...",
   "video.close": "Затвори видео",
   "video.exit_fullscreen": "Напусти цео екран",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 64d488324f334fcb8a62be23680554b11ea3418b..47ce8497a65b624616d257c41a7caa3d60ea9f84 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -1,17 +1,23 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Robot",
   "account.block": "Blockera @{name}",
   "account.block_domain": "Dölj allt från {domain}",
   "account.blocked": "Blockerad",
-  "account.direct": "Direct Message @{name}",
+  "account.direct": "Direktmeddelande @{name}",
   "account.disclaimer_full": "Informationen nedan kan spegla användarens profil ofullständigt.",
-  "account.domain_blocked": "Domän gömd",
+  "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.follows": "Följer",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Följer dig",
   "account.hide_reblogs": "Dölj knuffar från @{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": "Nämna @{name}",
   "account.moved_to": "{name} har flyttat till:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Visa knuffar från @{name}",
   "account.unblock": "Avblockera @{name}",
   "account.unblock_domain": "Ta fram {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Sluta följa",
   "account.unmute": "Ta bort tystad @{name}",
   "account.unmute_notifications": "Återaktivera notifikationer från @{name}",
@@ -86,6 +93,8 @@
   "confirmations.mute.message": "Är du säker du vill tysta ner {name}?",
   "confirmations.redraft.confirm": "Radera och gör om",
   "confirmations.redraft.message": "Är du säker på att du vill radera meddelandet och göra om det? Du kommer förlora alla svar, knuffar och favoriter som hänvisar till meddelandet.",
+  "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": "Sluta följa",
   "confirmations.unfollow.message": "Är du säker på att du vill sluta följa {name}?",
   "embed.instructions": "Bädda in den här statusen på din webbplats genom att kopiera koden nedan.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Sökresultat",
   "emoji_button.symbols": "Symboler",
   "emoji_button.travel": "Resor & Platser",
+  "empty_column.account_timeline": "No toots here!",
+  "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.",
+  "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": "Det finns inget i denna hashtag ännu.",
   "empty_column.home": "Din hemma-tidslinje är tom! Besök {public} eller använd sökning för att komma igång och träffa andra användare.",
   "empty_column.home.public_timeline": "den publika tidslinjen",
   "empty_column.list": "Det finns inget i denna lista än. När medlemmar i denna lista lägger till nya statusar kommer de att visas här.",
+  "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": "Du har inga meddelanden än. Interagera med andra för att starta konversationen.",
   "empty_column.public": "Det finns inget här! Skriv något offentligt, eller följ manuellt användarna från andra instanser för att fylla på det",
   "follow_request.authorize": "Godkänn",
   "follow_request.reject": "Avvisa",
   "getting_started.developers": "Utvecklare",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Hitta vänner från Twitter",
   "getting_started.heading": "Kom igång",
   "getting_started.invite": "Skicka inbjudningar",
   "getting_started.open_source_notice": "Mastodon är programvara med öppen källkod. Du kan bidra eller rapportera problem via GitHub på {github}.",
   "getting_started.security": "Säkerhet",
   "getting_started.terms": "Användarvillkor",
+  "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": "Grundläggande",
   "home.column_settings.show_reblogs": "Visa knuffar",
   "home.column_settings.show_replies": "Visa svar",
+  "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": "att navigera tillbaka",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
   "keyboard_shortcuts.boost": "att knuffa",
   "keyboard_shortcuts.column": "att fokusera en status i en av kolumnerna",
   "keyboard_shortcuts.compose": "att fokusera komponera text fältet",
   "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "keyboard_shortcuts.down": "att flytta ner i listan",
   "keyboard_shortcuts.enter": "to open status",
   "keyboard_shortcuts.favourite": "att favorisera",
+  "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": "Snabbvalstangent",
   "keyboard_shortcuts.legend": "att visa denna översikt",
+  "keyboard_shortcuts.local": "to open local timeline",
   "keyboard_shortcuts.mention": "att nämna författaren",
+  "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": "att svara",
+  "keyboard_shortcuts.requests": "to open follow requests list",
   "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.toot": "att börja en helt ny toot",
   "keyboard_shortcuts.unfocus": "att avfokusera komponera text fält / sökfält",
@@ -159,8 +213,10 @@
   "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.blocks": "Blockerade användare",
   "navigation_bar.community_timeline": "Lokal tidslinje",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direktmeddelanden",
   "navigation_bar.discover": "Upptäck",
   "navigation_bar.domain_blocks": "Dolda domäner",
@@ -186,35 +242,21 @@
   "notifications.clear_confirmation": "Är du säker på att du vill radera alla dina meddelanden permanent?",
   "notifications.column_settings.alert": "Skrivbordsmeddelanden",
   "notifications.column_settings.favourite": "Favoriter:",
+  "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": "Nya följare:",
   "notifications.column_settings.mention": "Omnämningar:",
   "notifications.column_settings.push": "Push meddelanden",
-  "notifications.column_settings.push_meta": "Denna anordning",
   "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.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} aviseringar",
-  "onboarding.done": "Klart",
-  "onboarding.next": "Nästa",
-  "onboarding.page_five.public_timelines": "Den lokala tidslinjen visar offentliga inlägg från alla på {domain}. Den förenade tidslinjen visar offentliga inlägg från alla personer på {domain} som följer. Dom här offentliga tidslinjerna är ett bra sätt att upptäcka nya människor.",
-  "onboarding.page_four.home": "Hemmatidslinjen visar inlägg från personer du följer.",
-  "onboarding.page_four.notifications": "Meddelandekolumnen visar när någon interagerar med dig.",
-  "onboarding.page_one.federation": "Mastodon är ett nätverk av oberoende servrar som ansluter för att skapa ett större socialt nätverk. Vi kallar dessa servrar instanser.",
-  "onboarding.page_one.full_handle": "Ditt fullständiga användarnamn/mastodonadress",
-  "onboarding.page_one.handle_hint": "Det här är vad du skulle berätta för dina vänner att söka efter.",
-  "onboarding.page_one.welcome": "Välkommen till Mastodon!",
-  "onboarding.page_six.admin": "Din instansadmin är {admin}.",
-  "onboarding.page_six.almost_done": "Snart klart...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Det finns {apps} tillgängligt för iOS, Android och andra plattformar.",
-  "onboarding.page_six.github": "Mastodon är fri programvara med öppen källkod. Du kan rapportera fel, efterfråga funktioner eller bidra till koden på {github}.",
-  "onboarding.page_six.guidelines": "gemenskapsriktlinjer",
-  "onboarding.page_six.read_guidelines": "Vänligen läs {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobilappar",
-  "onboarding.page_three.profile": "Redigera din profil för att ändra ditt avatar, bio och visningsnamn. Där hittar du även andra inställningar.",
-  "onboarding.page_three.search": "Använd sökfältet för att hitta personer och titta på hashtags, till exempel {illustration} och {introductions}. För att leta efter en person som inte befinner sig i detta fall använd deras fulla handhavande.",
-  "onboarding.page_two.compose": "Skriv inlägg från skrivkolumnen. Du kan ladda upp bilder, ändra integritetsinställningar och lägga till varningar med ikonerna nedan.",
-  "onboarding.skip": "Hoppa över",
   "privacy.change": "Justera sekretess",
   "privacy.direct.long": "Skicka endast till nämnda användare",
   "privacy.direct.short": "Direkt",
@@ -250,10 +292,13 @@
   "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.delete": "Ta bort",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direktmeddela @{name}",
   "status.embed": "Bädda in",
   "status.favourite": "Favorit",
@@ -267,9 +312,11 @@
   "status.open": "Utvidga denna status",
   "status.pin": "Fäst i profil",
   "status.pinned": "Fäst toot",
+  "status.read_more": "Read more",
   "status.reblog": "Knuff",
   "status.reblog_private": "Knuffa till de ursprungliga åhörarna",
   "status.reblogged_by": "{name} knuffade",
+  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
   "status.redraft": "Radera & gör om",
   "status.reply": "Svara",
   "status.replyAll": "Svara på tråden",
@@ -281,8 +328,11 @@
   "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.unmute_conversation": "Öppna konversation",
   "status.unpin": "Ångra fäst i profil",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Förenad",
   "tabs_bar.home": "Hem",
   "tabs_bar.local_timeline": "Lokal",
diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d510d011fd988fa03addb3c713686883efb4131
--- /dev/null
+++ b/app/javascript/mastodon/locales/ta.json
@@ -0,0 +1,358 @@
+{
+  "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",
+  "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",
+  "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",
+  "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.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": "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.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!",
+  "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": "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}}",
+  "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",
+  "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",
+  "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/te.json b/app/javascript/mastodon/locales/te.json
index 7e405b8c29c5e9f6d660ce1f416a6cddc87b62bc..7306ec00194d2a5ee59790186792b5e8d9a7a761 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "జాబితాల నుండి చేర్చు లేదా తీసివేయి",
   "account.badges.bot": "బాట్",
   "account.block": "@{name} ను బ్లాక్ చేయి",
   "account.block_domain": "{domain} నుంచి అన్నీ దాచిపెట్టు",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "క్రింది సమాచారం వాడుకరి యొక్క ప్రొఫైల్ను అసంపూర్తిగా ప్రతిబింబించవచ్చు.",
   "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} ఇక్కడికి మారారు:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "@{name}నుంచి బూస్ట్ లను చూపించు",
   "account.unblock": "@{name}పై బ్లాక్ ను తొలగించు",
   "account.unblock_domain": "{domain}ను దాచవద్దు",
+  "account.unendorse": "ప్రొఫైల్లో చూపించవద్దు",
   "account.unfollow": "అనుసరించవద్దు",
   "account.unmute": "@{name}పై మ్యూట్ ని తొలగించు",
   "account.unmute_notifications": "@{name} నుంచి ప్రకటనలపై మ్యూట్ ని తొలగించు",
@@ -65,7 +72,7 @@
   "compose_form.hashtag_warning": "ఈ టూట్ అన్లిస్టెడ్ కాబట్టి ఏ హాష్ ట్యాగ్ క్రిందకూ రాదు. పబ్లిక్ టూట్ లను మాత్రమే హాష్ ట్యాగ్ ద్వారా శోధించవచ్చు.",
   "compose_form.lock_disclaimer": "మీ ఖాతా {locked} చేయబడలేదు. ఎవరైనా మిమ్మల్ని అనుసరించి మీ అనుచరులకు-మాత్రమే పోస్ట్లను వీక్షించవచ్చు.",
   "compose_form.lock_disclaimer.lock": "బిగించబడినది",
-  "compose_form.placeholder": "మీ మనస్సులో ఏమి ఉంది?",
+  "compose_form.placeholder": "మీ మనస్సులో ఏముంది?",
   "compose_form.publish": "టూట్",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.marked": "మీడియా సున్నితమైనదిగా గుర్తించబడింది",
@@ -85,7 +92,9 @@
   "confirmations.mute.confirm": "మ్యూట్ చేయి",
   "confirmations.mute.message": "{name}ను మీరు ఖచ్చితంగా మ్యూట్ చేయాలనుకుంటున్నారా?",
   "confirmations.redraft.confirm": "తొలగించు & తిరగరాయు",
-  "confirmations.redraft.message": "మీరు ఖచ్చితంగా ఈ స్టేటస్ ని తొలగించి తిరగరాయాలనుకుంటున్నారా? మీరు అన్ని ప్రత్యుత్తరాలను, బూస్ట్ లను మరియు ఇష్టపడినవి కోల్పోతారు.",
+  "confirmations.redraft.message": "మీరు ఖచ్చితంగా ఈ స్టేటస్ ని తొలగించి తిరగరాయాలనుకుంటున్నారా? ఈ స్టేటస్ యొక్క బూస్ట్ లు మరియు ఇష్టాలు పోతాయి,మరియు ప్రత్యుత్తరాలు అనాధలు అయిపోతాయి.",
+  "confirmations.reply.confirm": "ప్రత్యుత్తరమివ్వు",
+  "confirmations.reply.message": "ఇప్పుడే ప్రత్యుత్తరం ఇస్తే మీరు ప్రస్తుతం వ్రాస్తున్న సందేశం తిరగరాయబడుతుంది. మీరు ఖచ్చితంగా కొనసాగించాలనుకుంటున్నారా?",
   "confirmations.unfollow.confirm": "అనుసరించవద్దు",
   "confirmations.unfollow.message": "{name}ను మీరు ఖచ్చితంగా అనుసరించవద్దనుకుంటున్నారా?",
   "embed.instructions": "దిగువ కోడ్ను కాపీ చేయడం ద్వారా మీ వెబ్సైట్లో ఈ స్టేటస్ ని పొందుపరచండి.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "శోధన ఫలితాలు",
   "emoji_button.symbols": "చిహ్నాలు",
   "emoji_button.travel": "ప్రయాణం & ప్రదేశాలు",
+  "empty_column.account_timeline": "ఇక్కడ ఏ టూట్లూ లేవు!No toots here!",
+  "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.documentation": "Documentation",
-  "getting_started.find_friends": "ట్విట్టర్ నుండి స్నేహితులను కనుగొనండి",
+  "getting_started.directory": "ప్రొఫైల్ డైరెక్టరీProfile directory",
+  "getting_started.documentation": "డాక్యుమెంటేషన్",
   "getting_started.heading": "మొదలుపెడదాం",
   "getting_started.invite": "వ్యక్తులను ఆహ్వానించండి",
   "getting_started.open_source_notice": "మాస్టొడొన్ ఓపెన్ సోర్స్ సాఫ్ట్వేర్. మీరు {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.tag_mode.all": "ఇవన్నీAll of these",
+  "hashtag.column_settings.tag_mode.any": "వీటిలో ఏవైనా",
+  "hashtag.column_settings.tag_mode.none": "ఇవేవీ కావు",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "ప్రాథమిక",
   "home.column_settings.show_reblogs": "బూస్ట్ లను చూపించు",
   "home.column_settings.show_replies": "ప్రత్యుత్తరాలను చూపించు",
+  "introduction.federation.action": "తరువాత",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "ఫెడివర్స్ లోని ఇతర సర్వర్లకు చెందిన పబ్లిక్ టూట్లు ఫెడరేటెడ్ టైంలైన్ లో కనిపిస్తాయి.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "మీరు అనుసరిస్తున్న ఖాతాల టూట్లు హోం ఫీడ్ లో కనిపిస్తాయి. ఏ సర్వర్లో ఎవరినైనా మీరు అనుసరించవచ్చు!",
+  "introduction.federation.local.headline": "Local",
+  "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": "Description",
+  "keyboard_shortcuts.direct": "నేరుగా పంపిన సందేశాల నిలువు వరుసను తెరువడానికి",
   "keyboard_shortcuts.down": "జాబితాలో క్రిందికి వెళ్ళడానికి",
   "keyboard_shortcuts.enter": "to open status",
   "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.toot": "ఒక సరికొత్త టూట్ను ప్రారంభించడానికి",
   "keyboard_shortcuts.unfocus": "పాఠ్యం వ్రాసే ఏరియా/శోధన పట్టిక నుండి బయటకు రావడానికి",
@@ -159,14 +213,16 @@
   "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": "Muted words",
+  "navigation_bar.filters": "మ్యూట్ చేయబడిన పదాలు",
   "navigation_bar.follow_requests": "అనుసరించడానికి అభ్యర్ధనలు",
   "navigation_bar.info": "ఈ దృష్టాంతం గురించి",
   "navigation_bar.keyboard_shortcuts": "హాట్ కీలు",
@@ -186,35 +242,21 @@
   "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.push": "పుష్ ప్రకటనలు",
-  "notifications.column_settings.push_meta": "ఈ పరికరం",
   "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.group": "{count} ప్రకటనలు",
-  "onboarding.done": "పూర్తయింది",
-  "onboarding.next": "తరువాత",
-  "onboarding.page_five.public_timelines": "స్థానిక కాలక్రమం {domain}లో ప్రతి ఒక్కరి నుండి పబ్లిక్ పోస్ట్లను చూపుతుంది. సమాఖ్య కాలక్రమం {డొమైన్} లోని వ్యక్తులు అనుసరించే ప్రతి ఒక్కరి నుండి పబ్లిక్ పోస్ట్లను చూపుతుంది. ఈ పబ్లిక్ కాలక్రమాలు క్రొత్త వ్యక్తులను కనుగొనడానికి ఒక గొప్ప మార్గం.",
-  "onboarding.page_four.home": "హోమ్ కాలక్రమం మీరు అనుసరించే వ్యక్తుల నుండి పోస్ట్లను చూపిస్తుంది.",
-  "onboarding.page_four.notifications": "ఎవరైనా మీతో సంభాషించినప్పుడు నోటిఫికేషన్ల నిలువు వరుసలో కనిపిస్తుంది.",
-  "onboarding.page_one.federation": "మాస్టొడొన్ అనేది అనేక స్వతంత్ర సేవికల సమాహారం వలన ఏర్పడిన ఒక సోషల్ నెట్వర్క్. మేము ఈ సేవికలను దుష్టాంతాలని అంటాము.",
-  "onboarding.page_one.full_handle": "మీ పూర్తి హ్యాండిల్",
-  "onboarding.page_one.handle_hint": "మీరు మీ స్నేహితులకు శోధించమని చెప్పేది ఇదే.",
-  "onboarding.page_one.welcome": "మాస్తోడాన్ కు స్వాగతం!",
-  "onboarding.page_six.admin": "మీ దృష్టాంతం యొక్క నిర్వాహకులు {admin}.",
-  "onboarding.page_six.almost_done": "దాదాపుగా అయిపోయింది...",
-  "onboarding.page_six.appetoot": "బాన్ ఆప్పెటూట్!",
-  "onboarding.page_six.apps_available": "iOS, Android మరియు ఇతర ప్లాట్ఫారమ్లకు {apps} అందుబాటులో ఉన్నాయి.",
-  "onboarding.page_six.github": "మాస్టొడొన్ ఉచిత ఓపెన్ సోర్స్ సాఫ్ట్వేర్. మీరు దోషాలను నివేదించవచ్చు, ఫీచర్లను అభ్యర్థించవచ్చు లేదా {github} లో కోడ్కు దోహదం చేయవచ్చు.",
-  "onboarding.page_six.guidelines": "సంఘం మార్గదర్శకాలు",
-  "onboarding.page_six.read_guidelines": "దయచేసి {domain} యొక్క {guidelines} చదవండి!",
-  "onboarding.page_six.various_app": "మొబైల్ అనువర్తనాలు",
-  "onboarding.page_three.profile": "మీ అవతార్, బయో, ప్రదర్శన పేరు మార్చడానికి మీ ప్రొఫైల్ను సవరించండి. అక్కడ, మీరు ఇతర ప్రాధాన్యతలను కూడా కనుగొంటారు.",
-  "onboarding.page_three.search": "వ్యక్తులను కనుగొనడానికి లేదా {illustration} మరియు {introductions} వంటి హ్యాష్ట్యాగ్లను చూడటానికి శోధన పట్టీని ఉపయోగించండి. ఈ దుష్టాంతంలో లేని ఒక వ్యక్తి కోసం శోధించేందుకు, వారి పూర్తి హ్యాండిల్ను ఉపయోగించండి.",
-  "onboarding.page_two.compose": "కంపోజ్ నిలువు వరుస నుండి పోస్ట్లను వ్రాయండి. మీరు చిత్రాలను అప్లోడ్ చెయ్యవచ్చు, గోప్యతా సెట్టింగ్లను మార్చవచ్చు మరియు దిగువ చిహ్నాలతో కంటెంట్ హెచ్చరికలను జోడించవచ్చు.",
-  "onboarding.skip": "దాటవేయి",
   "privacy.change": "స్టేటస్ గోప్యతను సర్దుబాటు చేయండి",
   "privacy.direct.long": "పేర్కొన్న వినియోగదారులకు మాత్రమే పోస్ట్ చేయి",
   "privacy.direct.short": "ప్రత్యక్ష",
@@ -250,14 +292,17 @@
   "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.delete": "తొలగించు",
+  "status.detailed_status": "వివరణాత్మక సంభాషణ వీక్షణ",
   "status.direct": "@{name}కు నేరుగా సందేశం పంపు",
   "status.embed": "ఎంబెడ్",
   "status.favourite": "ఇష్టపడు",
-  "status.filtered": "Filtered",
+  "status.filtered": "వడకట్టబడిన",
   "status.load_more": "మరిన్ని లోడ్ చేయి",
   "status.media_hidden": "మీడియా దాచబడింది",
   "status.mention": "@{name}ను ప్రస్తావించు",
@@ -267,9 +312,11 @@
   "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": "సంభాషణకు ప్రత్యుత్తరం ఇవ్వండి",
@@ -281,8 +328,11 @@
   "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": "స్థానిక",
@@ -291,9 +341,9 @@
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} మాట్లాడుతున్నారు",
   "ui.beforeunload": "మీరు మాస్టొడొన్ను వదిలివేస్తే మీ డ్రాఫ్ట్లు పోతాయి.",
   "upload_area.title": "అప్లోడ్ చేయడానికి డ్రాగ్ & డ్రాప్ చేయండి",
-  "upload_button.label": "మీడియాను జోడించండి",
+  "upload_button.label": "మీడియాను జోడించండి (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "దృష్టి లోపమున్న వారి కోసం వివరించండి",
-  "upload_form.focus": "కత్తిరించు",
+  "upload_form.focus": "ప్రివ్యూను మార్చు",
   "upload_form.undo": "తొలగించు",
   "upload_progress.label": "అప్లోడ్ అవుతోంది...",
   "video.close": "వీడియోని మూసివేయి",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 1d76735a236396be22b82cfc0b505a8a50010d45..2683284f4229ffd58a0c9517fd3ee8c0bbaa5eb1 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -1,4 +1,5 @@
 {
+  "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}",
@@ -7,11 +8,16 @@
   "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:",
@@ -26,6 +32,7 @@
   "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}",
@@ -86,6 +93,8 @@
   "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.",
@@ -104,41 +113,86 @@
   "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.find_friends": "Find friends from Twitter",
   "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",
+  "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.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
@@ -159,8 +213,10 @@
   "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",
@@ -186,35 +242,21 @@
   "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.push_meta": "This device",
   "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",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
-  "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -250,10 +292,13 @@
   "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.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
@@ -267,9 +312,11 @@
   "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",
@@ -281,8 +328,11 @@
   "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",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index 03a09019f89b7570bd8052f464bb7eb791fbce8b..5d8fc229e6d01755ad892d76597bb443c1b26a64 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "Bot",
   "account.block": "Engelle @{name}",
   "account.block_domain": "Hide everything from {domain}",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Profili düzenle",
+  "account.endorse": "Feature on profile",
   "account.follow": "Takip et",
   "account.followers": "Takipçiler",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Takip ettikleri",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "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:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "Show boosts from @{name}",
   "account.unblock": "Engeli kaldır @{name}",
   "account.unblock_domain": "Unhide {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Takipten vazgeç",
   "account.unmute": "Sesi aç @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
@@ -86,6 +93,8 @@
   "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.",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "Search results",
   "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.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.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",
   "follow_request.authorize": "Yetkilendir",
   "follow_request.reject": "Reddet",
   "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
   "getting_started.heading": "Başlangıç",
   "getting_started.invite": "Invite people",
   "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",
   "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",
+  "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": "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",
@@ -159,8 +213,10 @@
   "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",
   "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",
@@ -186,35 +242,21 @@
   "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.follow": "Yeni takipçiler:",
   "notifications.column_settings.mention": "Bahsedilenler:",
   "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
   "notifications.column_settings.reblog": "Boost’lar:",
   "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",
-  "onboarding.done": "Tamam",
-  "onboarding.next": "Sıradaki",
-  "onboarding.page_five.public_timelines": "Yerel zaman tüneli, bu sunucudaki herkesten gelen gönderileri gösterir.Federe zaman tüneli, kullanıcıların diğer sunuculardan takip ettiği kişilerin herkese açık gönderilerini gösterir. Bunlar herkese açık zaman tünelleridir ve yeni insanlarla tanışmak  için harika yerlerdir. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new ",
-  "onboarding.page_four.home": "Takip ettiğiniz insanlardan gelen gönderileri gosteren zaman tünelidir",
-  "onboarding.page_four.notifications": "Herkimse sizinle iletişime geçtiğinde gelen bildirimleri gösterir.",
-  "onboarding.page_one.federation": "Mastodon, geniş bir sosyal ağ kurmak için birleşen bağımsız sunuculardan oluşan bir ağdır.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Mastodon'a hoÅŸ geldiniz.",
-  "onboarding.page_six.admin": "{admin}, şu anda bulunduğunuz sunucunun yöneticisidir.",
-  "onboarding.page_six.almost_done": "Neredeyse tamam...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "iOS, Android ve diğer platformlar için {apps} mevcuttur",
-  "onboarding.page_six.github": "Mastodon açık kaynaklı bir yazılımdır. Github {github} üzerinden katkıda bulunabilir, özellik başvurusunda bulunabilir,hata raporlayabilirsiniz.",
-  "onboarding.page_six.guidelines": "topluluk kılavuzları",
-  "onboarding.page_six.read_guidelines": "Lütfen {domain}'in {guidelines} kılavuzlarını okuyunuz.",
-  "onboarding.page_six.various_app": "mobil uygulamalar",
-  "onboarding.page_three.profile": "Profil resminizi, kişisel bilgilerinizi ve görünen isminizi değiştirmek için profilinizi düzenleyebilirsiniz. Ayrıca diğer tercihlerinizi de düzenleyebilirsiniz.",
-  "onboarding.page_three.search": "Arama çubuğunu kullanarak kişileri bulabilir, ve {illustration} ve {introductions} gibi hashtag'leri arayabilirsiniz. Eğer bu sunucuda olmayan birini aramak istiyorsanız, kullanıcı adının tamamını yazarak arayabilirsiniz.",
-  "onboarding.page_two.compose": "Toot oluşturma alanını kullanarak gönderiler yazabilirsiniz. Aşağıdaki ikonları kullanarak görseller ekleyebilir, gizlilik ayarlarını değiştirebilir ve içerik uyarısı ekleyebilirsiniz.",
-  "onboarding.skip": "Geç",
   "privacy.change": "Gönderi gizliliğini ayarla",
   "privacy.direct.long": "Sadece bahsedilen kişilere gönder",
   "privacy.direct.short": "Direkt",
@@ -250,10 +292,13 @@
   "search_results.statuses": "Toots",
   "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.cannot_reblog": "Bu gönderi boost edilemez",
   "status.delete": "Sil",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favorilere ekle",
@@ -267,9 +312,11 @@
   "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.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.reply": "Cevapla",
   "status.replyAll": "Konuşmayı cevapla",
@@ -281,8 +328,11 @@
   "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.unmute_conversation": "Unmute conversation",
   "status.unpin": "Unpin from profile",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Federe",
   "tabs_bar.home": "Ana sayfa",
   "tabs_bar.local_timeline": "Yerel",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index 7bb2476d02af28d0a9abd4d36471faa5ac1fdaa3..606dda89fc61577baade109276566c5980d76e9e 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -1,220 +1,262 @@
 {
-  "account.badges.bot": "Bot",
-  "account.block": "Заблокувати",
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.badges.bot": "Бот",
+  "account.block": "Заблокувати @{name}",
   "account.block_domain": "Заглушити {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.blocked": "Заблоковані",
+  "account.direct": "Пряме повідомлення @{name}",
+  "account.disclaimer_full": "Інфомація знизу може відображати профіль користувача неповністю.",
+  "account.domain_blocked": "Домен приховано",
+  "account.edit_profile": "Редагувати профіль",
+  "account.endorse": "Feature on profile",
   "account.follow": "Підписатися",
   "account.followers": "Підписники",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "Підписки",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Підписаний(-а) на Вас",
-  "account.hide_reblogs": "Hide boosts from @{name}",
-  "account.media": "Медія",
-  "account.mention": "Згадати",
-  "account.moved_to": "{name} has moved to:",
-  "account.mute": "Заглушити",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
-  "account.posts": "Пости",
-  "account.posts_with_replies": "Toots with replies",
-  "account.report": "Поскаржитися",
-  "account.requested": "Очікує підтвердження",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
+  "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.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": "Розблокувати",
   "account.unblock_domain": "Розблокувати {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Відписатися",
-  "account.unmute": "Зняти глушення",
-  "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": "Зняти глушення @{name}",
+  "account.unmute_notifications": "Показувати сповіщення від @{name}",
+  "account.view_full_profile": "Показати профіль повністю",
+  "alert.unexpected.message": "Трапилась неочікувана помилка.",
+  "alert.unexpected.title": "Ой!",
   "boost_modal.combo": "Ви можете натиснути {combo}, щоб пропустити це наступного разу",
-  "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": "Щось пішло не так при завантаженні компоненту.",
+  "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": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
+  "column.direct": "Прямі повідомлення",
+  "column.domain_blocks": "Приховані домени",
   "column.favourites": "Вподобане",
   "column.follow_requests": "Запити на підписку",
   "column.home": "Головна",
-  "column.lists": "Lists",
+  "column.lists": "Списки",
   "column.mutes": "Заглушені користувачі",
   "column.notifications": "Сповіщення",
-  "column.pins": "Pinned toot",
+  "column.pins": "Закріплені дмухи",
   "column.public": "Глобальна стрічка",
   "column_back_button.label": "Назад",
-  "column_header.hide_settings": "Hide settings",
+  "column_header.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.moveRight_settings": "Змістити колонку вправо",
+  "column_header.pin": "Закріпити",
+  "column_header.show_settings": "Показати налаштування",
+  "column_header.unpin": "Відкріпити",
   "column_subheading.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.",
+  "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.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.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.confirm": "Заблокувати",
   "confirmations.block.message": "Ви впевнені, що хочете заблокувати {name}?",
   "confirmations.delete.confirm": "Видалити",
   "confirmations.delete.message": "Ви впевнені, що хочете видалити цей допис?",
-  "confirmations.delete_list.confirm": "Delete",
-  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
+  "confirmations.delete_list.confirm": "Видалити",
+  "confirmations.delete_list.message": "Ви впевнені, що хочете видалити цей список назавжди?",
   "confirmations.domain_block.confirm": "Сховати весь домен",
-  "confirmations.domain_block.message": "Ви точно, точно впевнені, що хочете заблокувати весь домен {domain}? У більшості випадків для нормальної роботи краще заблокувати/заглушити лише деяких користувачів.",
+  "confirmations.domain_block.message": "Ви точно, точно впевнені, що хочете заблокувати весь домен {domain}? У більшості випадків для нормальної роботи краще заблокувати/заглушити лише деяких користувачів. Ви не зможете бачити контент з цього домену у будь-яких стрічках або ваших сповіщеннях. Ваші підписники з цього домену будуть відписані від вас.",
   "confirmations.mute.confirm": "Заглушити",
   "confirmations.mute.message": "Ви впевнені, що хочете заглушити {name}?",
-  "confirmations.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.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": "Видалити і перестворити",
+  "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.unfollow.confirm": "Відписатися",
+  "confirmations.unfollow.message": "Ви впевнені, що хочете відписатися від {name}?",
+  "embed.instructions": "Інтегруйте цей статус на вашому вебсайті, скопіювавши код нижче.",
+  "embed.preview": "Ось як він виглядатиме:",
   "emoji_button.activity": "Заняття",
-  "emoji_button.custom": "Custom",
+  "emoji_button.custom": "Особливі",
   "emoji_button.flags": "Прапори",
   "emoji_button.food": "Їжа та напої",
   "emoji_button.label": "Вставити емодзі",
   "emoji_button.nature": "Природа",
-  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Немає емодзі!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Предмети",
   "emoji_button.people": "Люди",
-  "emoji_button.recent": "Frequently used",
+  "emoji_button.recent": "Часто використовувані",
   "emoji_button.search": "Знайти...",
-  "emoji_button.search_results": "Search results",
+  "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.community": "Локальна стрічка пуста. Напишіть щось, щоб розігріти народ!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "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.hashtag": "Дописів з цим хештегом поки не існує.",
   "empty_column.home": "Ви поки ні на кого не підписані. Погортайте {public}, або скористуйтесь пошуком, щоб освоїтися та познайомитися з іншими користувачами.",
   "empty_column.home.public_timeline": "публічні стрічки",
-  "empty_column.list": "There is nothing in this list yet.",
+  "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.notifications": "У вас ще немає сповіщень. Переписуйтесь з іншими користувачами, щоб почати розмову.",
-  "empty_column.public": "Тут поки нічого немає! Опублікуйте щось, або вручну підпишіться на користувачів інших інстанцій, щоб заповнити стрічку.",
+  "empty_column.public": "Тут поки нічого немає! Опублікуйте щось, або вручну підпишіться на користувачів інших інстанцій, щоб заповнити стрічку",
   "follow_request.authorize": "Авторизувати",
   "follow_request.reject": "Відмовити",
-  "getting_started.developers": "Developers",
-  "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.developers": "Розробникам",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Документація",
   "getting_started.heading": "Ласкаво просимо",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Запросіть людей",
   "getting_started.open_source_notice": "Mastodon - програма з відкритим вихідним кодом. Ви можете допомогти проекту, або повідомити про проблеми на GitHub за адресою {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
+  "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",
   "home.column_settings.basic": "Основні",
   "home.column_settings.show_reblogs": "Показувати передмухи",
   "home.column_settings.show_replies": "Показувати відповіді",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.boost": "to boost",
-  "keyboard_shortcuts.column": "to focus a status in one of the columns",
-  "keyboard_shortcuts.compose": "to focus the compose textarea",
-  "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.down": "to move down in the list",
-  "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.hotkey": "Hotkey",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.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.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": "to open blocked users list",
+  "keyboard_shortcuts.boost": "передмухувати",
+  "keyboard_shortcuts.column": "фокусуватися на одній з колонок",
+  "keyboard_shortcuts.compose": "фокусуватися на полі введення",
+  "keyboard_shortcuts.description": "Опис",
+  "keyboard_shortcuts.direct": "to open direct messages column",
+  "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.heading": "Гарячі клавіші",
+  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.hotkey": "Гаряча клавіша",
+  "keyboard_shortcuts.legend": "показати підказку",
+  "keyboard_shortcuts.local": "to open local timeline",
+  "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": "відкрити профіль автора",
+  "keyboard_shortcuts.reply": "відповісти",
+  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.search": "сфокусуватися на пошуку",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.toggle_hidden": "показати/приховати прихований текст",
+  "keyboard_shortcuts.toot": "почати писати новий дмух",
+  "keyboard_shortcuts.unfocus": "розфокусуватися з нового допису чи пошуку",
+  "keyboard_shortcuts.up": "рухатися вверх списком",
   "lightbox.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",
+  "lightbox.next": "Далі",
+  "lightbox.previous": "Назад",
+  "lists.account.add": "Додати до списку",
+  "lists.account.remove": "Видалити зі списку",
+  "lists.delete": "Видалити список",
+  "lists.edit": "Редагувати список",
+  "lists.new.create": "Додати список",
+  "lists.new.title_placeholder": "Нова назва списку",
+  "lists.search": "Шукати серед людей, на яких ви підписані",
+  "lists.subheading": "Ваші списки",
   "loading_indicator.label": "Завантаження...",
   "media_gallery.toggle_visible": "Показати/приховати",
   "missing_indicator.label": "Не знайдено",
-  "missing_indicator.sublabel": "This resource could not be found",
-  "mute_modal.hide_notifications": "Hide notifications from this user?",
+  "missing_indicator.sublabel": "Ресурс не знайдений",
+  "mute_modal.hide_notifications": "Приховати сповіщення від користувача?",
+  "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Заблоковані користувачі",
   "navigation_bar.community_timeline": "Локальна стрічка",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.compose": "Compose new toot",
+  "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.info": "Про інстанцію",
-  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
-  "navigation_bar.lists": "Lists",
+  "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.personal": "Особисте",
+  "navigation_bar.pins": "Закріплені дмухи",
   "navigation_bar.preferences": "Налаштування",
   "navigation_bar.public_timeline": "Глобальна стрічка",
-  "navigation_bar.security": "Security",
-  "notification.favourite": "{name} сподобався ваш допис",
+  "navigation_bar.security": "Безпека",
+  "notification.favourite": "{name} вподобав(-ла) ваш допис",
   "notification.follow": "{name} підписався(-лась) на Вас",
   "notification.mention": "{name} згадав(-ла) Вас",
   "notification.reblog": "{name} передмухнув(-ла) Ваш допис",
   "notifications.clear": "Очистити сповіщення",
-  "notifications.clear_confirmation": "Ви впевнені, що хочете видалити всі сповіщеня?",
-  "notifications.column_settings.alert": "Десктопні сповіщення",
+  "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.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
+  "notifications.column_settings.mention": "Згадки:",
+  "notifications.column_settings.push": "Push-сповіщення",
   "notifications.column_settings.reblog": "Передмухи:",
   "notifications.column_settings.show": "Показати в колонці",
-  "notifications.column_settings.sound": "Відтворювати звук",
-  "notifications.group": "{count} notifications",
-  "onboarding.done": "Готово",
-  "onboarding.next": "Далі",
-  "onboarding.page_five.public_timelines": "Локальна стрічка показує публічні пости усіх користувачів {domain}. Глобальна стрічка показує публічні пости усіх людей, на яких підписані користувачі {domain}. Це публичні стрічки, відмінний спосіб знайти нових людей.",
-  "onboarding.page_four.home": "Домашня стрічка показує пости користувачів, на яких Ви підписані.",
-  "onboarding.page_four.notifications": "Колонка сповіщень показує моменти, коли хтось звертається до Вас.",
-  "onboarding.page_one.federation": "Mastodon - це мережа незалежних серверів, які разом образовують єдину соціальну мережу. Ми называємо ці сервери інстанціями.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Ласкаво просимо до Mastodon!",
-  "onboarding.page_six.admin": "Адміністратором Вашої інстанції є {admin}.",
-  "onboarding.page_six.almost_done": "Майже готово...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "Для Mastodon існують {apps}, доступні для iOS, Android та інших платформ.",
-  "onboarding.page_six.github": "Ви можете допомогти проектові чи сповістити про проблеми на GitHub за адресою {github}.",
-  "onboarding.page_six.guidelines": "правила",
-  "onboarding.page_six.read_guidelines": "Будь ласка, прочитайте {guidelines} домену {domain}!",
-  "onboarding.page_six.various_app": "мобільні додатки",
-  "onboarding.page_three.profile": "Відредагуйте Ваш профіль, щоб змінити Ваши аватарку, інформацію та відображуване ім'я. Там Ви зможете знайти і інші налаштування.",
-  "onboarding.page_three.search": "Використовуйте рядок пошуку, щоб знайти інших людей та подивитися хештеги накшталт {illustration} та {introductions}. Для того, щоб знайти людину з іншої інстанції, використовуйте їхній повний нікнейм.",
-  "onboarding.page_two.compose": "Пишіть пости у колонці 'Написати'. Ви можете завантажувати зображення, міняти налаштування приватності та додавати попередження за допомогою піктограм знизу.",
-  "onboarding.skip": "Пропустити",
+  "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.group": "{count} сповіщень",
   "privacy.change": "Змінити видимість допису",
   "privacy.direct.long": "Показати тільки згаданим користувачам",
   "privacy.direct.short": "Направлений",
@@ -224,17 +266,17 @@
   "privacy.public.short": "Публічний",
   "privacy.unlisted.long": "Не показувати у публічних стрічках",
   "privacy.unlisted.short": "Прихований",
-  "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": "Завантаження…",
+  "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": "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": "Надіслати до {target}",
+  "report.forward_hint": "Це аккаунт з іншого серверу. Відправити анонімізовану копію скарги і туди?",
+  "report.hint": "Скаргу буде відправлено модераторам Вашого сайту. Ви можете надати їм пояснення, чому ви скаржитесь на аккаунт нижче:",
   "report.placeholder": "Додаткові коментарі",
   "report.submit": "Відправити",
   "report.target": "Скаржимося на",
@@ -250,10 +292,13 @@
   "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.delete": "Видалити",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Подобається",
@@ -267,9 +312,11 @@
   "status.open": "Розгорнути допис",
   "status.pin": "Pin on profile",
   "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
   "status.reblog": "Передмухнути",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "{name} передмухнув(-ла)",
+  "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": "Відповісти",
   "status.replyAll": "Відповісти на тред",
@@ -281,28 +328,31 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Розгорнути",
   "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Зняти глушення з діалогу",
   "status.unpin": "Unpin from profile",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "Глобальна",
   "tabs_bar.home": "Головна",
   "tabs_bar.local_timeline": "Локальна",
   "tabs_bar.notifications": "Сповіщення",
-  "tabs_bar.search": "Search",
+  "tabs_bar.search": "Пошук",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "ui.beforeunload": "Вашу чернетку буде втрачено, якщо ви покинете Mastodon.",
   "upload_area.title": "Перетягніть сюди, щоб завантажити",
   "upload_button.label": "Додати медіаконтент",
-  "upload_form.description": "Describe for the visually impaired",
-  "upload_form.focus": "Crop",
-  "upload_form.undo": "Відмінити",
+  "upload_form.description": "Опишіть для людей з вадами зору",
+  "upload_form.focus": "Обрізати",
+  "upload_form.undo": "Видалити",
   "upload_progress.label": "Завантаження...",
-  "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": "Закрити відео",
+  "video.exit_fullscreen": "Вийти з повного екрану",
+  "video.expand": "Розширити відео",
+  "video.fullscreen": "На весь екран",
+  "video.hide": "Приховати відео",
+  "video.mute": "Вимкнути звук",
+  "video.pause": "Призупинити",
+  "video.play": "Програвати",
+  "video.unmute": "Увімкнути звук"
 }
diff --git a/app/javascript/mastodon/locales/whitelist_ast.json b/app/javascript/mastodon/locales/whitelist_ast.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_ast.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_cy.json b/app/javascript/mastodon/locales/whitelist_cy.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_cy.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_ka.json b/app/javascript/mastodon/locales/whitelist_ka.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_ka.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_lv.json b/app/javascript/mastodon/locales/whitelist_lv.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_lv.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_ms.json b/app/javascript/mastodon/locales/whitelist_ms.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_ms.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_ro.json b/app/javascript/mastodon/locales/whitelist_ro.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_ro.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_ta.json b/app/javascript/mastodon/locales/whitelist_ta.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_ta.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 8b73bb8f99ce9c4aca94038f232d5c265812c36c..dfa261d6e4da3d9632988f3e2d422b8bc6c97dd9 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "机器人",
   "account.block": "屏蔽 @{name}",
   "account.block_domain": "隐藏来自 {domain} 的内容",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "此处显示的信息可能不是全部内容。",
   "account.domain_blocked": "网站已屏蔽",
   "account.edit_profile": "修改个人资料",
+  "account.endorse": "Feature on profile",
   "account.follow": "关注",
   "account.followers": "关注者",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "正在关注",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "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.media": "媒体",
   "account.mention": "提及 @{name}",
   "account.moved_to": "{name} 已经迁移到:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "显示来自 @{name} 的转嘟",
   "account.unblock": "不再屏蔽 @{name}",
   "account.unblock_domain": "不再隐藏来自 {domain} 的内容",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "取消关注",
   "account.unmute": "不再隐藏 @{name}",
   "account.unmute_notifications": "不再隐藏来自 @{name} 的通知",
@@ -86,6 +93,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.unfollow.confirm": "取消关注",
   "confirmations.unfollow.message": "你确定要取消关注 {name} 吗?",
   "embed.instructions": "要在你的网站上嵌入这条嘟文,请复制以下代码。",
@@ -104,41 +113,86 @@
   "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.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.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.notifications": "你还没有收到过任何通知,快向其他用户搭讪吧。",
   "empty_column.public": "这里神马都没有!写一些公开的嘟文,或者关注其他实例的用户后,这里就会有嘟文出现了哦!",
   "follow_request.authorize": "同意",
   "follow_request.reject": "拒绝",
   "getting_started.developers": "开发",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "文档",
-  "getting_started.find_friends": "寻找 Twitter 好友",
   "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",
   "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": "to open blocked users list",
   "keyboard_shortcuts.boost": "转嘟",
   "keyboard_shortcuts.column": "选择第 X 栏中的嘟文",
   "keyboard_shortcuts.compose": "选择嘟文撰写框",
   "keyboard_shortcuts.description": "说明",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "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.heading": "快捷键列表",
+  "keyboard_shortcuts.home": "to open home timeline",
   "keyboard_shortcuts.hotkey": "快捷键",
   "keyboard_shortcuts.legend": "显示此列表",
+  "keyboard_shortcuts.local": "to open local timeline",
   "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.reply": "回复嘟文",
+  "keyboard_shortcuts.requests": "to open follow requests list",
   "keyboard_shortcuts.search": "选择搜索框",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "显示或隐藏被折叠的正文",
   "keyboard_shortcuts.toot": "发送新嘟文",
   "keyboard_shortcuts.unfocus": "取消输入",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "找不到内容",
   "missing_indicator.sublabel": "无法找到此资源",
   "mute_modal.hide_notifications": "同时隐藏来自这个用户的通知",
+  "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "已屏蔽的用户",
   "navigation_bar.community_timeline": "本站时间轴",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "私信",
   "navigation_bar.discover": "发现",
   "navigation_bar.domain_blocks": "已屏蔽的网站",
@@ -186,35 +242,21 @@
   "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.push": "推送通知",
-  "notifications.column_settings.push_meta": "此设备",
   "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.group": "{count} 条通知",
-  "onboarding.done": "出发!",
-  "onboarding.next": "下一步",
-  "onboarding.page_five.public_timelines": "“本站时间轴”显示的是由本站({domain})用户发布的所有公开嘟文。“跨站公共时间轴”显示的的是由本站用户关注对象所发布的所有公开嘟文。这些就是寻人好去处的公共时间轴啦。",
-  "onboarding.page_four.home": "你的“主页”时间轴上显示的是你的关注对象所发布的嘟文。",
-  "onboarding.page_four.notifications": "如果有人与你互动了,他们就会出现在“通知”栏中哦~",
-  "onboarding.page_one.federation": "Mastodon 是由一系列独立的服务器共同打造的强大的社交网络,我们将这些各自独立而又相互连接的服务器叫做“实例”。",
-  "onboarding.page_one.full_handle": "你的完整用户地址",
-  "onboarding.page_one.handle_hint": "你的朋友们需要这个才能通过搜索功能找到你。",
-  "onboarding.page_one.welcome": "欢迎来到 Mastodon!",
-  "onboarding.page_six.admin": "{admin} 是你所在服务器实例的管理员。",
-  "onboarding.page_six.almost_done": "差不多了……",
-  "onboarding.page_six.appetoot": "嗷呜~",
-  "onboarding.page_six.apps_available": "我们还有适用于 iOS、Android 和其它平台的{apps}哦~",
-  "onboarding.page_six.github": "Mastodon 是自由的开源软件。欢迎前往 {github} 反馈问题、提出对新功能的建议或贡献代码 :-)",
-  "onboarding.page_six.guidelines": "社区指南",
-  "onboarding.page_six.read_guidelines": "别忘了看看 {domain} 的{guidelines}!",
-  "onboarding.page_six.various_app": "移动设备应用",
-  "onboarding.page_three.profile": "你还可以修改你的个人资料,比如头像、简介和昵称等偏好设置。",
-  "onboarding.page_three.search": "你可以通过搜索功能寻找用户和话题标签,比如“{illustration}”,或是“{introductions}”。如果你想搜索其他实例上的用户,就需要输入完整用户地址(@用户名@域名)哦。",
-  "onboarding.page_two.compose": "在撰写栏中开始嘟嘟吧!下方的按钮分别可以用来上传图片、修改嘟文可见范围,以及添加警告信息。",
-  "onboarding.skip": "跳过",
   "privacy.change": "设置嘟文可见范围",
   "privacy.direct.long": "只有被提及的用户能看到",
   "privacy.direct.short": "私信",
@@ -250,10 +292,13 @@
   "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.delete": "删除",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "发送私信给 @{name}",
   "status.embed": "嵌入",
   "status.favourite": "收藏",
@@ -267,9 +312,11 @@
   "status.open": "展开嘟文",
   "status.pin": "在个人资料页面置顶",
   "status.pinned": "置顶嘟文",
+  "status.read_more": "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.redraft": "删除并重新编辑",
   "status.reply": "回复",
   "status.replyAll": "回复所有人",
@@ -281,8 +328,11 @@
   "status.show_less_all": "隐藏所有内容",
   "status.show_more": "显示内容",
   "status.show_more_all": "显示所有内容",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "不再隐藏此对话",
   "status.unpin": "在个人资料页面取消置顶",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "跨站",
   "tabs_bar.home": "主页",
   "tabs_bar.local_timeline": "本站",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 21c3e61544b466da6460653fccb04fdac128252b..e57aa6d96dd2270829fdd8a85ca0f31d94899ed0 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -1,4 +1,5 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "account.badges.bot": "機械人",
   "account.block": "封鎖 @{name}",
   "account.block_domain": "隱藏來自 {domain} 的一切文章",
@@ -7,11 +8,16 @@
   "account.disclaimer_full": "下列資料不一定完整。",
   "account.domain_blocked": "服務站被隱藏",
   "account.edit_profile": "修改個人資料",
+  "account.endorse": "Feature on profile",
   "account.follow": "關注",
   "account.followers": "關注的人",
+  "account.followers.empty": "No one follows this user yet.",
   "account.follows": "正關注",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
   "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.media": "媒體",
   "account.mention": "提及 @{name}",
   "account.moved_to": "{name} 已經遷移到:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "顯示 @{name} 的推文",
   "account.unblock": "解除對 @{name} 的封鎖",
   "account.unblock_domain": "不再隱藏 {domain}",
+  "account.unendorse": "Don't feature on profile",
   "account.unfollow": "取消關注",
   "account.unmute": "取消 @{name} 的靜音",
   "account.unmute_notifications": "取消來自 @{name} 通知的靜音",
@@ -86,6 +93,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.unfollow.confirm": "取消關注",
   "confirmations.unfollow.message": "真的不要繼續關注 {name} 了嗎?",
   "embed.instructions": "要內嵌此文章,請將以下代碼貼進你的網站。",
@@ -104,41 +113,86 @@
   "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.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.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.notifications": "你沒有任何通知紀錄,快向其他用戶搭訕吧。",
   "empty_column.public": "跨站時間軸暫時沒有內容!快寫一些公共的文章,或者關注另一些服務站的用戶吧!你和本站、友站的交流,將決定這裏出現的內容。",
   "follow_request.authorize": "批准",
   "follow_request.reject": "拒絕",
   "getting_started.developers": "開發者",
+  "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "尋找 Twitter 好友",
   "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",
   "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": "to open blocked users list",
   "keyboard_shortcuts.boost": "轉推",
   "keyboard_shortcuts.column": "把標示移動到其中一列",
   "keyboard_shortcuts.compose": "把標示移動到文字輸入區",
   "keyboard_shortcuts.description": "描述",
+  "keyboard_shortcuts.direct": "to open direct messages column",
   "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.heading": "鍵盤快速鍵",
+  "keyboard_shortcuts.home": "to open home timeline",
   "keyboard_shortcuts.hotkey": "快速鍵",
   "keyboard_shortcuts.legend": "顯示這個說明",
+  "keyboard_shortcuts.local": "to open local timeline",
   "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.reply": "回覆",
+  "keyboard_shortcuts.requests": "to open follow requests list",
   "keyboard_shortcuts.search": "把標示移動到搜索",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "顯示或隱藏被標為敏感的文字",
   "keyboard_shortcuts.toot": "新的推文",
   "keyboard_shortcuts.unfocus": "把標示移離文字輸入和搜索",
@@ -159,8 +213,10 @@
   "missing_indicator.label": "找不到內容",
   "missing_indicator.sublabel": "無法找到內容",
   "mute_modal.hide_notifications": "隱藏來自這用戶的通知嗎?",
+  "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "被你封鎖的用戶",
   "navigation_bar.community_timeline": "本站時間軸",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "個人訊息",
   "navigation_bar.discover": "探索",
   "navigation_bar.domain_blocks": "隱藏的服務站",
@@ -186,35 +242,21 @@
   "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.push": "推送通知",
-  "notifications.column_settings.push_meta": "這臺設備",
   "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.group": "{count} 條通知",
-  "onboarding.done": "開始使用",
-  "onboarding.next": "繼續",
-  "onboarding.page_five.public_timelines": "「本站時間軸」顯示在 {domain} 各用戶的公開文章。「跨站時間軸」顯示在 {domain} 各人關注的所有用戶(包括其他服務站)的公開文章。這些都是「公共時間軸」,是認識新朋友的好地方。",
-  "onboarding.page_four.home": "「主頁」顯示你所關注用戶的文章。",
-  "onboarding.page_four.notifications": "「通知」欄顯示你和其他人的互動。",
-  "onboarding.page_one.federation": "Mastodon(萬象社交)是由一批獨立網站組成的龐大網絡,我們將這些獨立又互連網站稱為「服務站」(instance) 。",
-  "onboarding.page_one.full_handle": "你的帳號全名",
-  "onboarding.page_one.handle_hint": "朋友可以從這個帳號全名找到你。",
-  "onboarding.page_one.welcome": "歡迎使用 Mastodon(萬象社交)!",
-  "onboarding.page_six.admin": "你服務站的管理員是{admin}。",
-  "onboarding.page_six.almost_done": "差不多了……",
-  "onboarding.page_six.appetoot": "手機,你好!",
-  "onboarding.page_six.apps_available": "目前支援 Mastodon 的{apps}已經支援 iOS、Android 和其他系統平台。",
-  "onboarding.page_six.github": "Mastodon (萬象)是一個開源的程式,你可以在 {github} 上回報問題、提議新功能、或者參與開發貢獻。",
-  "onboarding.page_six.guidelines": "社群守則",
-  "onboarding.page_six.read_guidelines": "請留意閱讀 {domain} 的 {guidelines}!",
-  "onboarding.page_six.various_app": "各手機應用程式",
-  "onboarding.page_three.profile": "修改你個人頭像、簡介和顯示名稱,並可找到其他設定的頁面。",
-  "onboarding.page_three.search": "用「搜尋」框去找用戶或標籤像「{illustration}」和「{introductions}」。若你想找的人在別的服務站,請用完整的「@用戶名@網域」格式搜尋。",
-  "onboarding.page_two.compose": "在編寫欄寫你的文章。你可以在此上載圖片、修改文章的私隱度、及加入適當的內容警告。",
-  "onboarding.skip": "略過",
   "privacy.change": "調整私隱設定",
   "privacy.direct.long": "只有提及的用戶能看到",
   "privacy.direct.short": "私人訊息",
@@ -250,10 +292,13 @@
   "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.delete": "刪除",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "私訊 @{name}",
   "status.embed": "鑲嵌",
   "status.favourite": "收藏",
@@ -267,9 +312,11 @@
   "status.open": "展開文章",
   "status.pin": "置頂到資料頁",
   "status.pinned": "置頂文章",
+  "status.read_more": "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.redraft": "刪除並編輯",
   "status.reply": "回應",
   "status.replyAll": "回應所有人",
@@ -281,8 +328,11 @@
   "status.show_less_all": "減少顯示這類文章",
   "status.show_more": "顯示更多",
   "status.show_more_all": "顯示更多這類文章",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "解禁對話",
   "status.unpin": "解除置頂",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "跨站",
   "tabs_bar.home": "主頁",
   "tabs_bar.local_timeline": "本站",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index b4a70ef70af8aba992bd414be4cfe03970ed10ad..0cbe5da5aac1e143e2082a898a083b2ac5a2f058 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -1,17 +1,23 @@
 {
+  "account.add_or_remove_from_list": "Add or Remove from lists",
   "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.follow": "關注",
   "account.followers": "關注者",
+  "account.followers.empty": "還沒有人關注這個使用者。",
   "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.media": "媒體",
   "account.mention": "提到 @{name}",
   "account.moved_to": "{name} 已經移至:",
@@ -26,6 +32,7 @@
   "account.show_reblogs": "顯示來自 @{name} 的嘟文",
   "account.unblock": "取消封鎖 @{name}",
   "account.unblock_domain": "不再隱藏 {domain}",
+  "account.unendorse": "不再於個人資訊頁面上推薦對方",
   "account.unfollow": "取消關注",
   "account.unmute": "不再靜音 @{name}",
   "account.unmute_notifications": "不再對來自 @{name} 的通知靜音",
@@ -63,10 +70,10 @@
   "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": "你的帳號沒有{locked}。任何人都可以關注你,看到發給關注者的嘟文。",
   "compose_form.lock_disclaimer.lock": "上鎖",
   "compose_form.placeholder": "在想些什麼?",
-  "compose_form.publish": "貼掉",
+  "compose_form.publish": "嘟掉",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.marked": "此媒體已被標註為敏感的",
   "compose_form.sensitive.unmarked": "此媒體未被標註為敏感的",
@@ -85,10 +92,12 @@
   "confirmations.mute.confirm": "消音",
   "confirmations.mute.message": "你確定要消音 {name} ?",
   "confirmations.redraft.confirm": "刪除 & 編輯",
-  "confirmations.redraft.message": "你確定要刪除這條嘟文並重新編輯它嗎? 所有相關的回覆、轉嘟與最愛都會被刪除。",
+  "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.unfollow.confirm": "取消關注",
   "confirmations.unfollow.message": "真的不要繼續關注 {name} 了嗎?",
-  "embed.instructions": "要內嵌此貼文,請將以下代碼貼進你的網站。",
+  "embed.instructions": "要內嵌此嘟文,請將以下代碼貼進你的網站。",
   "embed.preview": "看上去會變成這樣:",
   "emoji_button.activity": "活動",
   "emoji_button.custom": "自訂",
@@ -104,41 +113,86 @@
   "emoji_button.search_results": "搜尋結果",
   "emoji_button.symbols": "符號",
   "emoji_button.travel": "旅遊與地點",
+  "empty_column.account_timeline": "No toots here!",
+  "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.list": "此份名單尚未有東西。當此名單的成員嘟出了新的狀態時,它們就會出現在這裡。",
+  "empty_column.lists": "你還沒有建立任何名單。你建立的名單將會顯示在這裡。",
+  "empty_column.mutes": "你還沒有靜音任何使用者。",
   "empty_column.notifications": "還沒有任何通知。和別的使用者互動來開始對話。",
   "empty_column.public": "這裡什麼都沒有! 寫一些公開的嘟文,或著關注其他站點的使用者後,這裡就會有嘟文出現了",
   "follow_request.authorize": "授權",
   "follow_request.reject": "拒絕",
   "getting_started.developers": "開發",
-  "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "尋找 Twitter 好友",
+  "getting_started.directory": "Profile 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",
   "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": "焦點移至撰寫文字區塊",
   "keyboard_shortcuts.description": "描述",
+  "keyboard_shortcuts.direct": "到私訊欄",
   "keyboard_shortcuts.down": "在列表往下移動",
-  "keyboard_shortcuts.enter": "to open status",
+  "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.toot": "新的嘟文",
   "keyboard_shortcuts.unfocus": "取消輸入",
@@ -159,14 +213,16 @@
   "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": "Muted words",
+  "navigation_bar.filters": "消音的詞",
   "navigation_bar.follow_requests": "關注請求",
   "navigation_bar.info": "關於本站",
   "navigation_bar.keyboard_shortcuts": "快捷鍵",
@@ -186,41 +242,27 @@
   "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.push": "推送通知",
-  "notifications.column_settings.push_meta": "這臺設備",
   "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.group": "{count} 條通知",
-  "onboarding.done": "完成",
-  "onboarding.next": "下一步",
-  "onboarding.page_five.public_timelines": "本站時間軸顯示 {domain} 上所有的公開嘟文。其他站點時間軸顯示 {domain} 上所有人關注的公開嘟文。這就是公開時間軸,發現新朋友的好地方。",
-  "onboarding.page_four.home": "主頁時間軸顯示所有你關注的人的嘟文。",
-  "onboarding.page_four.notifications": "通知欄顯示別人和你的互動。",
-  "onboarding.page_one.federation": "Mastodon 是由獨立的伺服器連結起來,形成的大社群網路。我們把這些伺服器稱為站點。",
-  "onboarding.page_one.full_handle": "你的完整帳戶名稱",
-  "onboarding.page_one.handle_hint": "你的朋友們可以從這個帳戶全名找到你。",
-  "onboarding.page_one.welcome": "歡迎來到 Mastodon !",
-  "onboarding.page_six.admin": "你的站點的管理員是 {admin} 。",
-  "onboarding.page_six.almost_done": "快好了…",
-  "onboarding.page_six.appetoot": "å—·å—š~!",
-  "onboarding.page_six.apps_available": "在 iOS 、 Android 和其他平台上有這些 {apps} 可以用。",
-  "onboarding.page_six.github": "Mastodon 是自由的開源軟體。你可以在 {github} 上回報問題、請求新功能或是做出貢獻。",
-  "onboarding.page_six.guidelines": "社群指南",
-  "onboarding.page_six.read_guidelines": "請閱讀 {domain} 的 {guidelines} !",
-  "onboarding.page_six.various_app": "行動版應用程式",
-  "onboarding.page_three.profile": "編輯你的頭貼、簡介與顯示名稱。你也可以在這邊找到其他設定。",
-  "onboarding.page_three.search": "利用搜尋列來找到其他人或是主題標籤,像是 {illustration} 或 {introductions} 。用完整的帳戶名稱來找其他站點上的使用者。",
-  "onboarding.page_two.compose": "在編輯欄寫些什麼。可以上傳圖片、改變隱私設定或是用下面的圖示加上內容警告。",
-  "onboarding.skip": "跳過",
   "privacy.change": "調整隱私狀態",
   "privacy.direct.long": "只有被提到的使用者能看到",
   "privacy.direct.short": "私訊",
   "privacy.private.long": "只有關注你的使用者能看到",
   "privacy.private.short": "僅關注者",
-  "privacy.public.long": "貼到公開時間軸",
+  "privacy.public.long": "嘟到公開時間軸",
   "privacy.public.short": "公開",
   "privacy.unlisted.long": "公開,但不會顯示在公開時間軸",
   "privacy.unlisted.short": "不公開",
@@ -250,14 +292,17 @@
   "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.delete": "刪除",
+  "status.detailed_status": "對話的詳細內容",
   "status.direct": "發送私訊給 @{name}",
   "status.embed": "嵌入",
   "status.favourite": "最愛",
-  "status.filtered": "Filtered",
+  "status.filtered": "已過濾",
   "status.load_more": "載入更多",
   "status.media_hidden": "隱藏媒體內容",
   "status.mention": "提到 @{name}",
@@ -267,9 +312,11 @@
   "status.open": "展開嘟文",
   "status.pin": "置頂到個人資訊頁",
   "status.pinned": "置頂嘟文",
+  "status.read_more": "Read more",
   "status.reblog": "轉嘟",
   "status.reblog_private": "轉嘟給原有關注者",
   "status.reblogged_by": "{name} 轉嘟了",
+  "status.reblogs.empty": "還沒有人轉嘟。如果有,會顯示在這裡。",
   "status.redraft": "刪除 & 編輯",
   "status.reply": "回覆",
   "status.replyAll": "回覆所有人",
@@ -281,8 +328,11 @@
   "status.show_less_all": "減少顯示這類嘟文",
   "status.show_more": "顯示更多",
   "status.show_more_all": "顯示更多這類嘟文",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "解除此對話的靜音",
   "status.unpin": "解除置頂",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
   "tabs_bar.federated_timeline": "其他站點",
   "tabs_bar.home": "主頁",
   "tabs_bar.local_timeline": "本站",
@@ -291,7 +341,7 @@
   "trends.count_by_accounts": "{count} 位使用者在討論",
   "ui.beforeunload": "如果離開 Mastodon,你的草稿將會不見。",
   "upload_area.title": "拖放來上傳",
-  "upload_button.label": "上傳媒體檔案",
+  "upload_button.label": "上傳媒體檔案 (JPEG, PNG, GIF, WebM, MP4, MOV)",
   "upload_form.description": "為視障人士增加文字說明",
   "upload_form.focus": "裁切",
   "upload_form.undo": "刪除",
diff --git a/app/javascript/mastodon/reducers/cards.js b/app/javascript/mastodon/reducers/cards.js
deleted file mode 100644
index 4d86b0d7e7a0821ee336ee2405d44717c167440d..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/reducers/cards.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import { STATUS_CARD_FETCH_SUCCESS } from '../actions/cards';
-
-import { Map as ImmutableMap, fromJS } from 'immutable';
-
-const initialState = ImmutableMap();
-
-export default function cards(state = initialState, action) {
-  switch(action.type) {
-  case STATUS_CARD_FETCH_SUCCESS:
-    return state.set(action.id, fromJS(action.card));
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 552f659c9276e7714ca60a78b8146313b1ef7e1f..1622871b8fff5c9d1765065af187119b59295733 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -51,6 +51,7 @@ const initialState = ImmutableMap({
   in_reply_to: null,
   is_composing: false,
   is_submitting: false,
+  is_changing_upload: false,
   is_uploading: false,
   progress: 0,
   media_attachments: ImmutableList(),
@@ -79,6 +80,7 @@ function clearAll(state) {
     map.set('spoiler', false);
     map.set('spoiler_text', '');
     map.set('is_submitting', false);
+    map.set('is_changing_upload', false);
     map.set('in_reply_to', null);
     map.set('privacy', state.get('default_privacy'));
     map.set('sensitive', false);
@@ -131,7 +133,7 @@ const updateSuggestionTags = (state, token) => {
 
   return state.merge({
     suggestions: state.get('tagHistory')
-      .filter(tag => tag.startsWith(prefix))
+      .filter(tag => tag.toLowerCase().startsWith(prefix.toLowerCase()))
       .slice(0, 4)
       .map(tag => '#' + tag),
     suggestion_token: token,
@@ -248,13 +250,15 @@ export default function compose(state = initialState, action) {
       map.set('idempotencyKey', uuid());
     });
   case COMPOSE_SUBMIT_REQUEST:
-  case COMPOSE_UPLOAD_CHANGE_REQUEST:
     return state.set('is_submitting', true);
+  case COMPOSE_UPLOAD_CHANGE_REQUEST:
+    return state.set('is_changing_upload', true);
   case COMPOSE_SUBMIT_SUCCESS:
     return clearAll(state);
   case COMPOSE_SUBMIT_FAIL:
-  case COMPOSE_UPLOAD_CHANGE_FAIL:
     return state.set('is_submitting', false);
+  case COMPOSE_UPLOAD_CHANGE_FAIL:
+    return state.set('is_changing_upload', false);
   case COMPOSE_UPLOAD_REQUEST:
     return state.set('is_uploading', true);
   case COMPOSE_UPLOAD_SUCCESS:
@@ -300,7 +304,7 @@ export default function compose(state = initialState, action) {
     return insertEmoji(state, action.position, action.emoji, action.needsSpace);
   case COMPOSE_UPLOAD_CHANGE_SUCCESS:
     return state
-      .set('is_submitting', false)
+      .set('is_changing_upload', false)
       .update('media_attachments', list => list.map(item => {
         if (item.get('id') === action.media.id) {
           return fromJS(action.media);
diff --git a/app/javascript/mastodon/reducers/conversations.js b/app/javascript/mastodon/reducers/conversations.js
new file mode 100644
index 0000000000000000000000000000000000000000..955a07754de087d0b1a74aaa1931f486ed2ee9a2
--- /dev/null
+++ b/app/javascript/mastodon/reducers/conversations.js
@@ -0,0 +1,102 @@
+import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
+import {
+  CONVERSATIONS_MOUNT,
+  CONVERSATIONS_UNMOUNT,
+  CONVERSATIONS_FETCH_REQUEST,
+  CONVERSATIONS_FETCH_SUCCESS,
+  CONVERSATIONS_FETCH_FAIL,
+  CONVERSATIONS_UPDATE,
+  CONVERSATIONS_READ,
+} from '../actions/conversations';
+import compareId from '../compare_id';
+
+const initialState = ImmutableMap({
+  items: ImmutableList(),
+  isLoading: false,
+  hasMore: true,
+  mounted: false,
+});
+
+const conversationToMap = item => ImmutableMap({
+  id: item.id,
+  unread: item.unread,
+  accounts: ImmutableList(item.accounts.map(a => a.id)),
+  last_status: item.last_status ? item.last_status.id : null,
+});
+
+const updateConversation = (state, item) => state.update('items', list => {
+  const index   = list.findIndex(x => x.get('id') === item.id);
+  const newItem = conversationToMap(item);
+
+  if (index === -1) {
+    return list.unshift(newItem);
+  } else {
+    return list.set(index, newItem);
+  }
+});
+
+const expandNormalizedConversations = (state, conversations, next) => {
+  let items = ImmutableList(conversations.map(conversationToMap));
+
+  return state.withMutations(mutable => {
+    if (!items.isEmpty()) {
+      mutable.update('items', list => {
+        list = list.map(oldItem => {
+          const newItemIndex = items.findIndex(x => x.get('id') === oldItem.get('id'));
+
+          if (newItemIndex === -1) {
+            return oldItem;
+          }
+
+          const newItem = items.get(newItemIndex);
+          items = items.delete(newItemIndex);
+
+          return newItem;
+        });
+
+        list = list.concat(items);
+
+        return list.sortBy(x => x.get('last_status'), (a, b) => {
+          if(a === null || b === null) {
+            return -1;
+          }
+
+          return compareId(a, b) * -1;
+        });
+      });
+    }
+
+    if (!next) {
+      mutable.set('hasMore', false);
+    }
+
+    mutable.set('isLoading', false);
+  });
+};
+
+export default function conversations(state = initialState, action) {
+  switch (action.type) {
+  case CONVERSATIONS_FETCH_REQUEST:
+    return state.set('isLoading', true);
+  case CONVERSATIONS_FETCH_FAIL:
+    return state.set('isLoading', false);
+  case CONVERSATIONS_FETCH_SUCCESS:
+    return expandNormalizedConversations(state, action.conversations, action.next);
+  case CONVERSATIONS_UPDATE:
+    return updateConversation(state, action.conversation);
+  case CONVERSATIONS_MOUNT:
+    return state.update('mounted', count => count + 1);
+  case CONVERSATIONS_UNMOUNT:
+    return state.update('mounted', count => count - 1);
+  case CONVERSATIONS_READ:
+    return state.update('items', list => list.map(item => {
+      if (item.get('id') === action.id) {
+        return item.set('unread', false);
+      }
+
+      return item;
+    }));
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/mastodon/reducers/dropdown_menu.js b/app/javascript/mastodon/reducers/dropdown_menu.js
index 5449884cc5834beb052d3954a1f3b920d0e0da44..36fd4f13217522000bab317a98a94cbcfc1aeed6 100644
--- a/app/javascript/mastodon/reducers/dropdown_menu.js
+++ b/app/javascript/mastodon/reducers/dropdown_menu.js
@@ -4,12 +4,12 @@ import {
   DROPDOWN_MENU_CLOSE,
 } from '../actions/dropdown_menu';
 
-const initialState = Immutable.Map({ openId: null, placement: null });
+const initialState = Immutable.Map({ openId: null, placement: null, keyboard: false });
 
 export default function dropdownMenu(state = initialState, action) {
   switch (action.type) {
   case DROPDOWN_MENU_OPEN:
-    return state.merge({ openId: action.id, placement: action.placement });
+    return state.merge({ openId: action.id, placement: action.placement, keyboard: action.keyboard });
   case DROPDOWN_MENU_CLOSE:
     return state.get('openId') === action.id ? state.set('openId', null) : state;
   default:
diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js
index 4a981fada9dfab7a295ab5f31394223381560ea7..0f0de849f789a0d1657768761bbbb43ba0b65d15 100644
--- a/app/javascript/mastodon/reducers/index.js
+++ b/app/javascript/mastodon/reducers/index.js
@@ -14,7 +14,6 @@ import relationships from './relationships';
 import settings from './settings';
 import push_notifications from './push_notifications';
 import status_lists from './status_lists';
-import cards from './cards';
 import mutes from './mutes';
 import reports from './reports';
 import contexts from './contexts';
@@ -26,7 +25,10 @@ import height_cache from './height_cache';
 import custom_emojis from './custom_emojis';
 import lists from './lists';
 import listEditor from './list_editor';
+import listAdder from './list_adder';
 import filters from './filters';
+import conversations from './conversations';
+import suggestions from './suggestions';
 
 const reducers = {
   dropdown_menu,
@@ -44,7 +46,6 @@ const reducers = {
   relationships,
   settings,
   push_notifications,
-  cards,
   mutes,
   reports,
   contexts,
@@ -56,7 +57,10 @@ const reducers = {
   custom_emojis,
   lists,
   listEditor,
+  listAdder,
   filters,
+  conversations,
+  suggestions,
 };
 
 export default combineReducers(reducers);
diff --git a/app/javascript/mastodon/reducers/list_adder.js b/app/javascript/mastodon/reducers/list_adder.js
new file mode 100644
index 0000000000000000000000000000000000000000..b8c1b0e26954b51b16cbf66d09a2a833d2a375a6
--- /dev/null
+++ b/app/javascript/mastodon/reducers/list_adder.js
@@ -0,0 +1,47 @@
+import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
+import {
+  LIST_ADDER_RESET,
+  LIST_ADDER_SETUP,
+  LIST_ADDER_LISTS_FETCH_REQUEST,
+  LIST_ADDER_LISTS_FETCH_SUCCESS,
+  LIST_ADDER_LISTS_FETCH_FAIL,
+  LIST_EDITOR_ADD_SUCCESS,
+  LIST_EDITOR_REMOVE_SUCCESS,
+} from '../actions/lists';
+
+const initialState = ImmutableMap({
+  accountId: null,
+
+  lists: ImmutableMap({
+    items: ImmutableList(),
+    loaded: false,
+    isLoading: false,
+  }),
+});
+
+export default function listAdderReducer(state = initialState, action) {
+  switch(action.type) {
+  case LIST_ADDER_RESET:
+    return initialState;
+  case LIST_ADDER_SETUP:
+    return state.withMutations(map => {
+      map.set('accountId', action.account.get('id'));
+    });
+  case LIST_ADDER_LISTS_FETCH_REQUEST:
+    return state.setIn(['lists', 'isLoading'], true);
+  case LIST_ADDER_LISTS_FETCH_FAIL:
+    return state.setIn(['lists', 'isLoading'], false);
+  case LIST_ADDER_LISTS_FETCH_SUCCESS:
+    return state.update('lists', lists => lists.withMutations(map => {
+      map.set('isLoading', false);
+      map.set('loaded', true);
+      map.set('items', ImmutableList(action.lists.map(item => item.id)));
+    }));
+  case LIST_EDITOR_ADD_SUCCESS:
+    return state.updateIn(['lists', 'items'], list => list.unshift(action.listId));
+  case LIST_EDITOR_REMOVE_SUCCESS:
+    return state.updateIn(['lists', 'items'], list => list.filterNot(item => item === action.listId));
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js
index 84d4fc69888f05f91dda66bed3ee3d67f69231fc..19a02f5b1546bde84e802d8ab854f5f3f2295a03 100644
--- a/app/javascript/mastodon/reducers/notifications.js
+++ b/app/javascript/mastodon/reducers/notifications.js
@@ -3,6 +3,7 @@ import {
   NOTIFICATIONS_EXPAND_SUCCESS,
   NOTIFICATIONS_EXPAND_REQUEST,
   NOTIFICATIONS_EXPAND_FAIL,
+  NOTIFICATIONS_FILTER_SET,
   NOTIFICATIONS_CLEAR,
   NOTIFICATIONS_SCROLL_TOP,
 } from '../actions/notifications';
@@ -26,6 +27,7 @@ const notificationToMap = notification => ImmutableMap({
   id: notification.id,
   type: notification.type,
   account: notification.account.id,
+  created_at: notification.created_at,
   status: notification.status ? notification.status.id : null,
 });
 
@@ -68,7 +70,7 @@ const expandNormalizedNotifications = (state, notifications, next) => {
     }
 
     if (!next) {
-      mutable.set('hasMore', true);
+      mutable.set('hasMore', false);
     }
 
     mutable.set('isLoading', false);
@@ -97,6 +99,8 @@ export default function notifications(state = initialState, action) {
     return state.set('isLoading', true);
   case NOTIFICATIONS_EXPAND_FAIL:
     return state.set('isLoading', false);
+  case NOTIFICATIONS_FILTER_SET:
+    return state.set('items', ImmutableList()).set('hasMore', true);
   case NOTIFICATIONS_SCROLL_TOP:
     return updateTop(state, action.top);
   case NOTIFICATIONS_UPDATE:
diff --git a/app/javascript/mastodon/reducers/relationships.js b/app/javascript/mastodon/reducers/relationships.js
index d1caabc1c702cd88d08a9f4654b3836a5223b3aa..8322780de569d68c26f88dcac12b90d716d4d61e 100644
--- a/app/javascript/mastodon/reducers/relationships.js
+++ b/app/javascript/mastodon/reducers/relationships.js
@@ -1,10 +1,16 @@
 import {
   ACCOUNT_FOLLOW_SUCCESS,
+  ACCOUNT_FOLLOW_REQUEST,
+  ACCOUNT_FOLLOW_FAIL,
   ACCOUNT_UNFOLLOW_SUCCESS,
+  ACCOUNT_UNFOLLOW_REQUEST,
+  ACCOUNT_UNFOLLOW_FAIL,
   ACCOUNT_BLOCK_SUCCESS,
   ACCOUNT_UNBLOCK_SUCCESS,
   ACCOUNT_MUTE_SUCCESS,
   ACCOUNT_UNMUTE_SUCCESS,
+  ACCOUNT_PIN_SUCCESS,
+  ACCOUNT_UNPIN_SUCCESS,
   RELATIONSHIPS_FETCH_SUCCESS,
 } from '../actions/accounts';
 import {
@@ -35,12 +41,22 @@ const initialState = ImmutableMap();
 
 export default function relationships(state = initialState, action) {
   switch(action.type) {
+  case ACCOUNT_FOLLOW_REQUEST:
+    return state.setIn([action.id, action.locked ? 'requested' : 'following'], true);
+  case ACCOUNT_FOLLOW_FAIL:
+    return state.setIn([action.id, action.locked ? 'requested' : 'following'], false);
+  case ACCOUNT_UNFOLLOW_REQUEST:
+    return state.setIn([action.id, 'following'], false);
+  case ACCOUNT_UNFOLLOW_FAIL:
+    return state.setIn([action.id, 'following'], true);
   case ACCOUNT_FOLLOW_SUCCESS:
   case ACCOUNT_UNFOLLOW_SUCCESS:
   case ACCOUNT_BLOCK_SUCCESS:
   case ACCOUNT_UNBLOCK_SUCCESS:
   case ACCOUNT_MUTE_SUCCESS:
   case ACCOUNT_UNMUTE_SUCCESS:
+  case ACCOUNT_PIN_SUCCESS:
+  case ACCOUNT_UNPIN_SUCCESS:
     return normalizeRelationship(state, action.relationship);
   case RELATIONSHIPS_FETCH_SUCCESS:
     return normalizeRelationships(state, action.relationships);
diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js
index 12bcc2583faaf3188f72b77dc8f91d0d76259913..2e1878cf782e526c54fa1d9916eb397a7fb187ce 100644
--- a/app/javascript/mastodon/reducers/settings.js
+++ b/app/javascript/mastodon/reducers/settings.js
@@ -1,4 +1,5 @@
 import { SETTING_CHANGE, SETTING_SAVE } from '../actions/settings';
+import { NOTIFICATIONS_FILTER_SET } from '../actions/notifications';
 import { COLUMN_ADD, COLUMN_REMOVE, COLUMN_MOVE, COLUMN_PARAMS_CHANGE } from '../actions/columns';
 import { STORE_HYDRATE } from '../actions/store';
 import { EMOJI_USE } from '../actions/emojis';
@@ -32,6 +33,12 @@ const initialState = ImmutableMap({
       mention: true,
     }),
 
+    quickFilter: ImmutableMap({
+      active: 'all',
+      show: true,
+      advanced: false,
+    }),
+
     shows: ImmutableMap({
       follow: true,
       favourite: true,
@@ -112,6 +119,7 @@ export default function settings(state = initialState, action) {
   switch(action.type) {
   case STORE_HYDRATE:
     return hydrate(state, action.state.get('settings'));
+  case NOTIFICATIONS_FILTER_SET:
   case SETTING_CHANGE:
     return state
       .setIn(action.path, action.value)
diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js
index 3abe69bcead081e514cf65874f18c1a22fc922b4..885cc221cd4d29ddb5dabffa4c207f276efa5e90 100644
--- a/app/javascript/mastodon/reducers/statuses.js
+++ b/app/javascript/mastodon/reducers/statuses.js
@@ -38,22 +38,30 @@ export default function statuses(state = initialState, action) {
   case FAVOURITE_REQUEST:
     return state.setIn([action.status.get('id'), 'favourited'], true);
   case FAVOURITE_FAIL:
-    return state.setIn([action.status.get('id'), 'favourited'], false);
+    return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'favourited'], false);
   case REBLOG_REQUEST:
     return state.setIn([action.status.get('id'), 'reblogged'], true);
   case REBLOG_FAIL:
-    return state.setIn([action.status.get('id'), 'reblogged'], false);
+    return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], false);
   case STATUS_MUTE_SUCCESS:
     return state.setIn([action.id, 'muted'], true);
   case STATUS_UNMUTE_SUCCESS:
     return state.setIn([action.id, 'muted'], false);
   case STATUS_REVEAL:
     return state.withMutations(map => {
-      action.ids.forEach(id => map.setIn([id, 'hidden'], false));
+      action.ids.forEach(id => {
+        if (!(state.get(id) === undefined)) {
+          map.setIn([id, 'hidden'], false);
+        }
+      });
     });
   case STATUS_HIDE:
     return state.withMutations(map => {
-      action.ids.forEach(id => map.setIn([id, 'hidden'], true));
+      action.ids.forEach(id => {
+        if (!(state.get(id) === undefined)) {
+          map.setIn([id, 'hidden'], true);
+        }
+      });
     });
   case TIMELINE_DELETE:
     return deleteStatus(state, action.id, action.references);
diff --git a/app/javascript/mastodon/reducers/suggestions.js b/app/javascript/mastodon/reducers/suggestions.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f4b89d58659714dd370557ff1736124dc07b91a
--- /dev/null
+++ b/app/javascript/mastodon/reducers/suggestions.js
@@ -0,0 +1,30 @@
+import {
+  SUGGESTIONS_FETCH_REQUEST,
+  SUGGESTIONS_FETCH_SUCCESS,
+  SUGGESTIONS_FETCH_FAIL,
+  SUGGESTIONS_DISMISS,
+} from '../actions/suggestions';
+import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
+
+const initialState = ImmutableMap({
+  items: ImmutableList(),
+  isLoading: false,
+});
+
+export default function suggestionsReducer(state = initialState, action) {
+  switch(action.type) {
+  case SUGGESTIONS_FETCH_REQUEST:
+    return state.set('isLoading', true);
+  case SUGGESTIONS_FETCH_SUCCESS:
+    return state.withMutations(map => {
+      map.set('items', fromJS(action.accounts.map(x => x.id)));
+      map.set('isLoading', false);
+    });
+  case SUGGESTIONS_FETCH_FAIL:
+    return state.set('isLoading', false);
+  case SUGGESTIONS_DISMISS:
+    return state.update('items', list => list.filterNot(id => id === action.id));
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js
index 916a091eb9bc69075de2402ce0a99e1ce810e4aa..1f7ece8122f2e3f74c935c11ee117232d42f9f18 100644
--- a/app/javascript/mastodon/reducers/timelines.js
+++ b/app/javascript/mastodon/reducers/timelines.js
@@ -1,6 +1,7 @@
 import {
   TIMELINE_UPDATE,
   TIMELINE_DELETE,
+  TIMELINE_CLEAR,
   TIMELINE_EXPAND_SUCCESS,
   TIMELINE_EXPAND_REQUEST,
   TIMELINE_EXPAND_FAIL,
@@ -25,10 +26,10 @@ const initialTimeline = ImmutableMap({
   items: ImmutableList(),
 });
 
-const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial) => {
+const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, isLoadingRecent) => {
   return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
     mMap.set('isLoading', false);
-    if (!next) mMap.set('hasMore', false);
+    if (!next && !isLoadingRecent) mMap.set('hasMore', false);
 
     if (!statuses.isEmpty()) {
       mMap.update('items', ImmutableList(), oldIds => {
@@ -86,6 +87,10 @@ const deleteStatus = (state, id, accountId, references) => {
   return state;
 };
 
+const clearTimeline = (state, timeline) => {
+  return state.set(timeline, initialTimeline);
+};
+
 const filterTimelines = (state, relationship, statuses) => {
   let references;
 
@@ -121,11 +126,13 @@ export default function timelines(state = initialState, action) {
   case TIMELINE_EXPAND_FAIL:
     return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
   case TIMELINE_EXPAND_SUCCESS:
-    return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial);
+    return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent);
   case TIMELINE_UPDATE:
     return updateTimeline(state, action.timeline, fromJS(action.status));
   case TIMELINE_DELETE:
     return deleteStatus(state, action.id, action.accountId, action.references, action.reblogOf);
+  case TIMELINE_CLEAR:
+    return clearTimeline(state, action.timeline);
   case ACCOUNT_BLOCK_SUCCESS:
   case ACCOUNT_MUTE_SUCCESS:
     return filterTimelines(state, action.relationship, action.statuses);
diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js
index 106198f7449cc31192b557582c1f743bbfdb92f2..70f08a8eb5e0dd610cbc54bb69a07d781b216872 100644
--- a/app/javascript/mastodon/selectors/index.js
+++ b/app/javascript/mastodon/selectors/index.js
@@ -1,5 +1,6 @@
 import { createSelector } from 'reselect';
 import { List as ImmutableList } from 'immutable';
+import { me } from '../initial_state';
 
 const getAccountBase         = (state, id) => state.getIn(['accounts', id], null);
 const getAccountCounters     = (state, id) => state.getIn(['accounts_counters', id], null);
@@ -83,7 +84,7 @@ export const makeGetStatus = () => {
         statusReblog = null;
       }
 
-      const regex    = regexFromFilters(filters);
+      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'));
 
       return statusBase.withMutations(map => {
diff --git a/app/javascript/mastodon/service_worker/web_push_notifications.js b/app/javascript/mastodon/service_worker/web_push_notifications.js
index 3318bbadccf0b71d1c7bce6e79b963df93ab29af..1ab0dc0faacd7dd4df013f366d1fd70366944e18 100644
--- a/app/javascript/mastodon/service_worker/web_push_notifications.js
+++ b/app/javascript/mastodon/service_worker/web_push_notifications.js
@@ -80,15 +80,7 @@ const handlePush = (event) => {
 
   // Placeholder until more information can be loaded
   event.waitUntil(
-    notify({
-      title,
-      body,
-      icon,
-      tag: notification_id,
-      timestamp: new Date(),
-      badge: '/badge.png',
-      data: { access_token, preferred_locale, url: '/web/notifications' },
-    }).then(() => fetchFromApi(`/api/v1/notifications/${notification_id}`, 'get', access_token)).then(notification => {
+    fetchFromApi(`/api/v1/notifications/${notification_id}`, 'get', access_token).then(notification => {
       const options = {};
 
       options.title     = formatMessage(`notification.${notification.type}`, preferred_locale, { name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
@@ -100,11 +92,14 @@ const handlePush = (event) => {
       options.image     = notification.status && notification.status.media_attachments.length > 0 && notification.status.media_attachments[0].preview_url || undefined;
       options.data      = { access_token, preferred_locale, id: notification.status ? notification.status.id : notification.account.id, url: notification.status ? `/web/statuses/${notification.status.id}` : `/web/accounts/${notification.account.id}` };
 
-      if (notification.status && notification.status.sensitive) {
+      if (notification.status && notification.status.spoiler_text || notification.status.sensitive) {
         options.data.hiddenBody  = htmlToPlainText(notification.status.content);
         options.data.hiddenImage = notification.status.media_attachments.length > 0 && notification.status.media_attachments[0].preview_url;
 
-        options.body    = notification.status.spoiler_text;
+        if (notification.status.spoiler_text) {
+          options.body    = notification.status.spoiler_text;
+        }
+
         options.image   = undefined;
         options.actions = [actionExpand(preferred_locale)];
       } else if (notification.type === 'mention') {
@@ -112,6 +107,16 @@ const handlePush = (event) => {
       }
 
       return notify(options);
+    }).catch(() => {
+      return notify({
+        title,
+        body,
+        icon,
+        tag: notification_id,
+        timestamp: new Date(),
+        badge: '/badge.png',
+        data: { access_token, preferred_locale, url: '/web/notifications' },
+      });
     })
   );
 };
@@ -166,7 +171,7 @@ const openUrl = url =>
 
       if (webClients.length !== 0) {
         const client       = findBestClient(webClients);
-        const { pathname } = new URL(url);
+        const { pathname } = new URL(url, self.location);
 
         if (pathname.startsWith('/web/')) {
           return client.focus().then(client => client.postMessage({
diff --git a/app/javascript/mastodon/store/configureStore.js b/app/javascript/mastodon/store/configureStore.js
index 1376d4cbaf566e37d957281ea390dac8f386616d..7e7472841aa74676e2ca6b6c62f556f4f2292af2 100644
--- a/app/javascript/mastodon/store/configureStore.js
+++ b/app/javascript/mastodon/store/configureStore.js
@@ -11,5 +11,5 @@ export default function configureStore() {
     loadingBarMiddleware({ promiseTypeSuffixes: ['REQUEST', 'SUCCESS', 'FAIL'] }),
     errorsMiddleware(),
     soundsMiddleware()
-  ), window.devToolsExtension ? window.devToolsExtension() : f => f));
+  ), window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f));
 };
diff --git a/app/javascript/mastodon/utils/resize_image.js b/app/javascript/mastodon/utils/resize_image.js
index 279a858cad314ee40be3468b007adb695fb8ffae..d1608094f7f379592ac43820fd8014c5b4a53e97 100644
--- a/app/javascript/mastodon/utils/resize_image.js
+++ b/app/javascript/mastodon/utils/resize_image.js
@@ -1,6 +1,6 @@
 import EXIF from 'exif-js';
 
-const MAX_IMAGE_DIMENSION = 1280;
+const MAX_IMAGE_PIXELS = 1638400; // 1280x1280px
 
 const getImageUrl = inputFile => new Promise((resolve, reject) => {
   if (window.URL && URL.createObjectURL) {
@@ -73,18 +73,8 @@ const processImage = (img, { width, height, orientation, type = 'image/png' }) =
 const resizeImage = (img, type = 'image/png') => new Promise((resolve, reject) => {
   const { width, height } = img;
 
-  let newWidth, newHeight;
-
-  if (width > height) {
-    newHeight = height * MAX_IMAGE_DIMENSION / width;
-    newWidth  = MAX_IMAGE_DIMENSION;
-  } else if (height > width) {
-    newWidth  = width * MAX_IMAGE_DIMENSION / height;
-    newHeight = MAX_IMAGE_DIMENSION;
-  } else {
-    newWidth  = MAX_IMAGE_DIMENSION;
-    newHeight = MAX_IMAGE_DIMENSION;
-  }
+  const newWidth  = Math.round(Math.sqrt(MAX_IMAGE_PIXELS * (width / height)));
+  const newHeight = Math.round(Math.sqrt(MAX_IMAGE_PIXELS * (height / width)));
 
   getOrientation(img, type)
     .then(orientation => processImage(img, {
@@ -104,7 +94,7 @@ export default inputFile => new Promise((resolve, reject) => {
   }
 
   loadImage(inputFile).then(img => {
-    if (img.width < MAX_IMAGE_DIMENSION && img.height < MAX_IMAGE_DIMENSION) {
+    if (img.width * img.height < MAX_IMAGE_PIXELS) {
       resolve(inputFile);
       return;
     }
diff --git a/app/javascript/packs/about.js b/app/javascript/packs/about.js
index 63e12da42ccfe3ec029bfb4c1fd9c65d9f32d810..843cb2c87d43860242a16b32852452f597080f78 100644
--- a/app/javascript/packs/about.js
+++ b/app/javascript/packs/about.js
@@ -1,4 +1,7 @@
 import loadPolyfills from '../mastodon/load_polyfills';
+import { start } from '../mastodon/common';
+
+start();
 
 function loaded() {
   const TimelineContainer = require('../mastodon/containers/timeline_container').default;
diff --git a/app/javascript/packs/admin.js b/app/javascript/packs/admin.js
index 5dbcc03d3941d08dfe171f2f201753acd3fcf4d8..f0c0ee0b74eb10ccf67a8ed65c703ba89ae3893b 100644
--- a/app/javascript/packs/admin.js
+++ b/app/javascript/packs/admin.js
@@ -1,17 +1,5 @@
 import { delegate } from 'rails-ujs';
 
-function handleDeleteStatus(event) {
-  const [data] = event.detail;
-  const element = document.querySelector(`[data-id="${data.id}"]`);
-  if (element) {
-    element.parentNode.removeChild(element);
-  }
-}
-
-[].forEach.call(document.querySelectorAll('.trash-button'), (content) => {
-  content.addEventListener('ajax:success', handleDeleteStatus);
-});
-
 const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]';
 
 delegate(document, '#batch_checkbox_all', 'change', ({ target }) => {
@@ -22,6 +10,7 @@ delegate(document, '#batch_checkbox_all', 'change', ({ target }) => {
 
 delegate(document, batchCheckboxClassName, 'change', () => {
   const checkAllElement = document.querySelector('#batch_checkbox_all');
+
   if (checkAllElement) {
     checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked);
     checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked);
@@ -39,3 +28,16 @@ delegate(document, '.media-spoiler-hide-button', 'click', () => {
     element.click();
   });
 });
+
+delegate(document, '#domain_block_severity', 'change', ({ target }) => {
+  const rejectMediaDiv   = document.querySelector('.input.with_label.domain_block_reject_media');
+  const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports');
+
+  if (rejectMediaDiv) {
+    rejectMediaDiv.style.display = (target.value === 'suspend') ? 'none' : 'block';
+  }
+
+  if (rejectReportsDiv) {
+    rejectReportsDiv.style.display = (target.value === 'suspend') ? 'none' : 'block';
+  }
+});
diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js
index 116632dea704a860b7c3881e203f189f5f4612ac..c65ebed74f8b94abf31111d7aa395e2a33a42ba4 100644
--- a/app/javascript/packs/application.js
+++ b/app/javascript/packs/application.js
@@ -1,4 +1,7 @@
 import loadPolyfills from '../mastodon/load_polyfills';
+import { start } from '../mastodon/common';
+
+start();
 
 loadPolyfills().then(() => {
   require('../mastodon/main').default();
diff --git a/app/javascript/packs/common.js b/app/javascript/packs/common.js
deleted file mode 100644
index 96e6f4b16f496f96dc0f45bd682af1ac6f2eee30..0000000000000000000000000000000000000000
--- a/app/javascript/packs/common.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import { start } from 'rails-ujs';
-import 'font-awesome/css/font-awesome.css';
-
-require.context('../images/', true);
-
-start();
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js
index 5b9c1967255d6dbf57bbd58cce251730faa5c5ce..4ab27c769281e433b38a1e9427a82371186b8286 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.js
@@ -1,5 +1,9 @@
+import escapeTextContentForBrowser from 'escape-html';
 import loadPolyfills from '../mastodon/load_polyfills';
 import ready from '../mastodon/ready';
+import { start } from '../mastodon/common';
+
+start();
 
 window.addEventListener('message', e => {
   const data = e.data || {};
@@ -18,16 +22,27 @@ window.addEventListener('message', e => {
 });
 
 function main() {
-  const { length } = require('stringz');
-  const IntlRelativeFormat = require('intl-relativeformat').default;
+  const IntlMessageFormat = require('intl-messageformat').default;
+  const { timeAgoString } = require('../mastodon/components/relative_timestamp');
   const { delegate } = require('rails-ujs');
   const emojify = require('../mastodon/features/emoji/emoji').default;
   const { getLocale } = require('../mastodon/locales');
-  const { localeData } = getLocale();
+  const { messages } = getLocale();
   const React = require('react');
   const ReactDOM = require('react-dom');
+  const Rellax = require('rellax');
+  const createHistory = require('history').createBrowserHistory;
+
+  const scrollToDetailedStatus = () => {
+    const history = createHistory();
+    const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status');
+    const location = history.location;
 
-  localeData.forEach(IntlRelativeFormat.__addLocaleData);
+    if (detailedStatuses.length === 1 && (!location.state || !location.state.scrolledToDetailedStatus)) {
+      detailedStatuses[0].scrollIntoView();
+      history.replace(location.pathname, { ...location.state, scrolledToDetailedStatus: true });
+    }
+  };
 
   ready(() => {
     const locale = document.documentElement.lang;
@@ -40,8 +55,6 @@ function main() {
       minute: 'numeric',
     });
 
-    const relativeFormat = new IntlRelativeFormat(locale);
-
     [].forEach.call(document.querySelectorAll('.emojify'), (content) => {
       content.innerHTML = emojify(content.innerHTML);
     });
@@ -56,28 +69,52 @@ function main() {
 
     [].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
       const datetime = new Date(content.getAttribute('datetime'));
+      const now      = new Date();
 
       content.title = dateTimeFormat.format(datetime);
-      content.textContent = relativeFormat.format(datetime);
-    });
-
-    [].forEach.call(document.querySelectorAll('.logo-button'), (content) => {
-      content.addEventListener('click', (e) => {
-        e.preventDefault();
-        window.open(e.target.href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
-      });
+      content.textContent = timeAgoString({
+        formatMessage: ({ id, defaultMessage }, values) => (new IntlMessageFormat(messages[id] || defaultMessage, locale)).format(values),
+        formatDate: (date, options) => (new Intl.DateTimeFormat(locale, options)).format(date),
+      }, datetime, now, now.getFullYear());
     });
 
     const reactComponents = document.querySelectorAll('[data-component]');
+
     if (reactComponents.length > 0) {
       import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container')
         .then(({ default: MediaContainer }) => {
+          [].forEach.call(reactComponents, (component) => {
+            [].forEach.call(component.children, (child) => {
+              component.removeChild(child);
+            });
+          });
+
           const content = document.createElement('div');
 
           ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content);
           document.body.appendChild(content);
+          scrollToDetailedStatus();
         })
-        .catch(error => console.error(error));
+        .catch(error => {
+          console.error(error);
+          scrollToDetailedStatus();
+        });
+    } else {
+      scrollToDetailedStatus();
+    }
+
+    const parallaxComponents = document.querySelectorAll('.parallax');
+
+    if (parallaxComponents.length > 0 ) {
+      new Rellax('.parallax', { speed: -1 });
+    }
+
+    if (document.body.classList.contains('with-modals')) {
+      const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
+      const scrollbarWidthStyle = document.createElement('style');
+      scrollbarWidthStyle.id = 'scrollbar-width';
+      document.head.appendChild(scrollbarWidthStyle);
+      scrollbarWidthStyle.sheet.insertRule(`body.with-modals--active { margin-right: ${scrollbarWidth}px; }`, 0);
     }
   });
 
@@ -103,24 +140,33 @@ function main() {
     return false;
   });
 
-  delegate(document, '.account_display_name', 'input', ({ target }) => {
-    const nameCounter = document.querySelector('.name-counter');
+  delegate(document, '.modal-button', 'click', e => {
+    e.preventDefault();
 
-    if (nameCounter) {
-      nameCounter.textContent = 30 - length(target.value);
+    let href;
+
+    if (e.target.nodeName !== 'A') {
+      href = e.target.parentNode.href;
+    } else {
+      href = e.target.href;
     }
-  });
 
-  delegate(document, '.account_note', 'input', ({ target }) => {
-    const noteCounter = document.querySelector('.note-counter');
+    window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
+  });
 
-    if (noteCounter) {
-      noteCounter.textContent = 65535 - length(target.value);
+  delegate(document, '#account_display_name', 'input', ({ target }) => {
+    const name = document.querySelector('.card .display-name strong');
+    if (name) {
+      if (target.value) {
+        name.innerHTML = emojify(escapeTextContentForBrowser(target.value));
+      } else {
+        name.textContent = document.querySelector('#default_account_display_name').textContent;
+      }
     }
   });
 
   delegate(document, '#account_avatar', 'change', ({ target }) => {
-    const avatar = document.querySelector('.card.compact .avatar img');
+    const avatar = document.querySelector('.card .avatar img');
     const [file] = target.files || [];
     const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
 
@@ -128,11 +174,45 @@ function main() {
   });
 
   delegate(document, '#account_header', 'change', ({ target }) => {
-    const header = document.querySelector('.card.compact');
+    const header = document.querySelector('.card .card__img img');
     const [file] = target.files || [];
     const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc;
 
-    header.style.backgroundImage = `url(${url})`;
+    header.src = url;
+  });
+
+  delegate(document, '#account_locked', 'change', ({ target }) => {
+    const lock = document.querySelector('.card .display-name i');
+
+    if (target.checked) {
+      lock.style.display = 'inline';
+    } else {
+      lock.style.display = 'none';
+    }
+  });
+
+  delegate(document, '.input-copy input', 'click', ({ target }) => {
+    target.select();
+  });
+
+  delegate(document, '.input-copy button', 'click', ({ target }) => {
+    const input = target.parentNode.querySelector('.input-copy__wrapper input');
+
+    input.focus();
+    input.select();
+
+    try {
+      if (document.execCommand('copy')) {
+        input.blur();
+        target.parentNode.classList.add('copied');
+
+        setTimeout(() => {
+          target.parentNode.classList.remove('copied');
+        }, 700);
+      }
+    } catch (err) {
+      console.error(err);
+    }
   });
 }
 
diff --git a/app/javascript/packs/share.js b/app/javascript/packs/share.js
index e9580f648bf0df4b5719ab4d1352c46f4cffdf64..4ef23e1b2e9b8ef705ff07a4d9e468df39d89801 100644
--- a/app/javascript/packs/share.js
+++ b/app/javascript/packs/share.js
@@ -1,4 +1,7 @@
 import loadPolyfills from '../mastodon/load_polyfills';
+import { start } from '../mastodon/common';
+
+start();
 
 function loaded() {
   const ComposeContainer = require('../mastodon/containers/compose_container').default;
diff --git a/app/javascript/styles/application.scss b/app/javascript/styles/application.scss
index 268d7c11d07ec6a678e8121a0b1b10416b62a118..0eae63247c16ea9893c60bb4e8914064fded710b 100644
--- a/app/javascript/styles/application.scss
+++ b/app/javascript/styles/application.scss
@@ -10,17 +10,19 @@
 @import 'mastodon/lists';
 @import 'mastodon/footer';
 @import 'mastodon/compact_header';
-@import 'mastodon/landing_strip';
+@import 'mastodon/widgets';
 @import 'mastodon/forms';
 @import 'mastodon/accounts';
 @import 'mastodon/stream_entries';
 @import 'mastodon/boost';
 @import 'mastodon/components';
+@import 'mastodon/introduction';
 @import 'mastodon/modal';
 @import 'mastodon/emoji_picker';
 @import 'mastodon/about';
 @import 'mastodon/tables';
 @import 'mastodon/admin';
+@import 'mastodon/dashboard';
 @import 'mastodon/rtl';
 @import 'mastodon/accessibility';
 
diff --git a/app/javascript/styles/mailer.scss b/app/javascript/styles/mailer.scss
index dbe070f9a3c22fa5c9d6e6605a2c5bc9d7d6c63f..74d1df8ed3edd9318352aa5bfa1d3baf6a2f7800 100644
--- a/app/javascript/styles/mailer.scss
+++ b/app/javascript/styles/mailer.scss
@@ -169,7 +169,7 @@ p {
   font-family: Helvetica, Arial, sans-serif;
 
   @media only screen {
-    font-family: 'mastodon-font-sans-serif', sans-serif !important;
+    font-family: $font-sans-serif, sans-serif !important;
   }
 }
 
@@ -426,6 +426,10 @@ h5 {
     background: $success-green;
   }
 
+  &.alert-icon td {
+    background: $error-red;
+  }
+
   img {
     max-width: 32px;
     width: 32px;
diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss
index 84ccd326ec8b8ec35df3253f58203ed804548b6b..78bc2dbb6d50e0ab8371f7d28676492feb95c48e 100644
--- a/app/javascript/styles/mastodon-light/diff.scss
+++ b/app/javascript/styles/mastodon-light/diff.scss
@@ -169,6 +169,10 @@
   color: $white;
 }
 
+.dropdown-menu__separator {
+  border-bottom-color: lighten($ui-base-color, 12%);
+}
+
 // Change the background colors of modals
 .actions-modal,
 .boost-modal,
@@ -281,3 +285,73 @@
     }
   }
 }
+
+.simple_form,
+.table-form {
+  .warning {
+    box-shadow: none;
+    background: rgba($error-red, 0.5);
+    text-shadow: none;
+  }
+}
+
+.status__content,
+.reply-indicator__content {
+  a {
+    color: $highlight-text-color;
+  }
+}
+
+.button.logo-button {
+  color: $white;
+
+  svg path:first-child {
+    fill: $white;
+  }
+}
+
+.public-layout {
+  .header,
+  .public-account-header,
+  .public-account-bio {
+    box-shadow: none;
+  }
+
+  .header {
+    background: lighten($ui-base-color, 12%);
+  }
+
+  .public-account-header {
+    &__image {
+      background: lighten($ui-base-color, 12%);
+
+      &::after {
+        box-shadow: none;
+      }
+    }
+
+    &__tabs {
+      &__name {
+        h1,
+        h1 small {
+          color: $white;
+        }
+      }
+    }
+  }
+}
+
+.account__section-headline a.active::after {
+  border-color: transparent transparent $white;
+}
+
+.hero-widget,
+.box-widget,
+.contact-widget,
+.landing-page__information.contact-widget,
+.moved-account-widget,
+.memoriam-widget,
+.activity-stream,
+.nothing-here {
+  box-shadow: none;
+}
diff --git a/app/javascript/styles/mastodon/_mixins.scss b/app/javascript/styles/mastodon/_mixins.scss
index 67d768a6c6e34413babf9a12a61ec0d8ea6dd209..d5bafe6b6a2e7a6b13371d8d9b4a87ea634f384d 100644
--- a/app/javascript/styles/mastodon/_mixins.scss
+++ b/app/javascript/styles/mastodon/_mixins.scss
@@ -10,3 +10,34 @@
   height: $size;
   background-size: $size $size;
 }
+
+@mixin search-input() {
+  outline: 0;
+  box-sizing: border-box;
+  width: 100%;
+  border: none;
+  box-shadow: none;
+  font-family: inherit;
+  background: $ui-base-color;
+  color: $darker-text-color;
+  font-size: 14px;
+  margin: 0;
+
+  &::-moz-focus-inner {
+    border: 0;
+  }
+
+  &::-moz-focus-inner,
+  &:focus,
+  &:active {
+    outline: 0 !important;
+  }
+
+  &:focus {
+    background: lighten($ui-base-color, 4%);
+  }
+
+  @media screen and (max-width: 600px) {
+    font-size: 16px;
+  }
+}
diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss
index 19e14fe95284d095176e6ada2bd0ca41290dc65b..c6f249fabdf5257b7477627a981f904865e63ea3 100644
--- a/app/javascript/styles/mastodon/about.scss
+++ b/app/javascript/styles/mastodon/about.scss
@@ -15,6 +15,276 @@ $small-breakpoint: 960px;
   }
 }
 
+.rich-formatting {
+  font-family: $font-sans-serif, sans-serif;
+  font-size: 16px;
+  font-weight: 400;
+  font-size: 16px;
+  line-height: 30px;
+  color: $darker-text-color;
+  padding-right: 10px;
+
+  a {
+    color: $highlight-text-color;
+    text-decoration: underline;
+  }
+
+  p,
+  li {
+    font-family: $font-sans-serif, sans-serif;
+    font-size: 16px;
+    font-weight: 400;
+    font-size: 16px;
+    line-height: 30px;
+    margin-bottom: 12px;
+    color: $darker-text-color;
+
+    a {
+      color: $highlight-text-color;
+      text-decoration: underline;
+    }
+
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+
+  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%);
+  }
+
+  h1 {
+    font-family: $font-display, sans-serif;
+    font-size: 26px;
+    line-height: 30px;
+    font-weight: 500;
+    margin-bottom: 20px;
+    color: $secondary-text-color;
+
+    small {
+      font-family: $font-sans-serif, sans-serif;
+      display: block;
+      font-size: 18px;
+      font-weight: 400;
+      color: lighten($darker-text-color, 10%);
+    }
+  }
+
+  h2 {
+    font-family: $font-display, sans-serif;
+    font-size: 22px;
+    line-height: 26px;
+    font-weight: 500;
+    margin-bottom: 20px;
+    color: $secondary-text-color;
+  }
+
+  h3 {
+    font-family: $font-display, sans-serif;
+    font-size: 18px;
+    line-height: 24px;
+    font-weight: 500;
+    margin-bottom: 20px;
+    color: $secondary-text-color;
+  }
+
+  h4 {
+    font-family: $font-display, sans-serif;
+    font-size: 16px;
+    line-height: 24px;
+    font-weight: 500;
+    margin-bottom: 20px;
+    color: $secondary-text-color;
+  }
+
+  h5 {
+    font-family: $font-display, sans-serif;
+    font-size: 14px;
+    line-height: 24px;
+    font-weight: 500;
+    margin-bottom: 20px;
+    color: $secondary-text-color;
+  }
+
+  h6 {
+    font-family: $font-display, sans-serif;
+    font-size: 12px;
+    line-height: 24px;
+    font-weight: 500;
+    margin-bottom: 20px;
+    color: $secondary-text-color;
+  }
+
+  ul,
+  ol {
+    margin-left: 20px;
+
+    &[type='a'] {
+      list-style-type: lower-alpha;
+    }
+
+    &[type='i'] {
+      list-style-type: lower-roman;
+    }
+  }
+
+  ul {
+    list-style: disc;
+  }
+
+  ol {
+    list-style: decimal;
+  }
+
+  li > ol,
+  li > ul {
+    margin-top: 6px;
+  }
+
+  hr {
+    width: 100%;
+    height: 0;
+    border: 0;
+    border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
+    margin: 20px 0;
+
+    &.spacer {
+      height: 1px;
+      border: 0;
+    }
+  }
+}
+
+.information-board {
+  background: darken($ui-base-color, 4%);
+  padding: 20px 0;
+
+  .container-alt {
+    position: relative;
+    padding-right: 280px + 15px;
+  }
+
+  &__sections {
+    display: flex;
+    justify-content: space-between;
+    flex-wrap: wrap;
+  }
+
+  &__section {
+    flex: 1 0 0;
+    font-family: $font-sans-serif, sans-serif;
+    font-size: 16px;
+    line-height: 28px;
+    color: $primary-text-color;
+    text-align: right;
+    padding: 10px 15px;
+
+    span,
+    strong {
+      display: block;
+    }
+
+    span {
+      &:last-child {
+        color: $secondary-text-color;
+      }
+    }
+
+    strong {
+      font-weight: 500;
+      font-size: 32px;
+      line-height: 48px;
+    }
+
+    @media screen and (max-width: $column-breakpoint) {
+      text-align: center;
+    }
+  }
+
+  .panel {
+    position: absolute;
+    width: 280px;
+    box-sizing: border-box;
+    background: darken($ui-base-color, 8%);
+    padding: 20px;
+    padding-top: 10px;
+    border-radius: 4px 4px 0 0;
+    right: 0;
+    bottom: -40px;
+
+    .panel-header {
+      font-family: $font-display, sans-serif;
+      font-size: 14px;
+      line-height: 24px;
+      font-weight: 500;
+      color: $darker-text-color;
+      padding-bottom: 5px;
+      margin-bottom: 15px;
+      border-bottom: 1px solid lighten($ui-base-color, 4%);
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      overflow: hidden;
+
+      a,
+      span {
+        font-weight: 400;
+        color: darken($darker-text-color, 10%);
+      }
+
+      a {
+        text-decoration: none;
+      }
+    }
+  }
+
+  .owner {
+    text-align: center;
+
+    .avatar {
+      width: 80px;
+      height: 80px;
+      margin: 0 auto;
+      margin-bottom: 15px;
+
+      img {
+        display: block;
+        width: 80px;
+        height: 80px;
+        border-radius: 48px;
+      }
+    }
+
+    .name {
+      font-size: 14px;
+
+      a {
+        display: block;
+        color: $primary-text-color;
+        text-decoration: none;
+
+        &:hover {
+          .display_name {
+            text-decoration: underline;
+          }
+        }
+      }
+
+      .username {
+        display: block;
+        color: $darker-text-color;
+      }
+    }
+  }
+}
+
 .landing-page {
   .grid {
     display: grid;
@@ -94,7 +364,7 @@ $small-breakpoint: 960px;
 
   @media screen and (max-width: $column-breakpoint) {
     .grid {
-      grid-template-columns: auto;
+      grid-template-columns: 100%;
 
       .column-0 {
         display: block;
@@ -180,7 +450,7 @@ $small-breakpoint: 960px;
 
   p,
   li {
-    font-family: 'mastodon-font-sans-serif', sans-serif;
+    font-family: $font-sans-serif, sans-serif;
     font-size: 16px;
     font-weight: 400;
     font-size: 16px;
@@ -229,7 +499,7 @@ $small-breakpoint: 960px;
   }
 
   h1 {
-    font-family: 'mastodon-font-display', sans-serif;
+    font-family: $font-display, sans-serif;
     font-size: 26px;
     line-height: 30px;
     font-weight: 500;
@@ -237,7 +507,7 @@ $small-breakpoint: 960px;
     color: $secondary-text-color;
 
     small {
-      font-family: 'mastodon-font-sans-serif', sans-serif;
+      font-family: $font-sans-serif, sans-serif;
       display: block;
       font-size: 18px;
       font-weight: 400;
@@ -246,7 +516,7 @@ $small-breakpoint: 960px;
   }
 
   h2 {
-    font-family: 'mastodon-font-display', sans-serif;
+    font-family: $font-display, sans-serif;
     font-size: 22px;
     line-height: 26px;
     font-weight: 500;
@@ -255,7 +525,7 @@ $small-breakpoint: 960px;
   }
 
   h3 {
-    font-family: 'mastodon-font-display', sans-serif;
+    font-family: $font-display, sans-serif;
     font-size: 18px;
     line-height: 24px;
     font-weight: 500;
@@ -264,7 +534,7 @@ $small-breakpoint: 960px;
   }
 
   h4 {
-    font-family: 'mastodon-font-display', sans-serif;
+    font-family: $font-display, sans-serif;
     font-size: 16px;
     line-height: 24px;
     font-weight: 500;
@@ -273,7 +543,7 @@ $small-breakpoint: 960px;
   }
 
   h5 {
-    font-family: 'mastodon-font-display', sans-serif;
+    font-family: $font-display, sans-serif;
     font-size: 14px;
     line-height: 24px;
     font-weight: 500;
@@ -282,7 +552,7 @@ $small-breakpoint: 960px;
   }
 
   h6 {
-    font-family: 'mastodon-font-display', sans-serif;
+    font-family: $font-display, sans-serif;
     font-size: 12px;
     line-height: 24px;
     font-weight: 500;
@@ -349,7 +619,7 @@ $small-breakpoint: 960px;
 
       .hero .heading {
         padding-bottom: 20px;
-        font-family: 'mastodon-font-sans-serif', sans-serif;
+        font-family: $font-sans-serif, sans-serif;
         font-size: 16px;
         font-weight: 400;
         font-size: 16px;
@@ -400,7 +670,7 @@ $small-breakpoint: 960px;
         text-decoration: none;
         padding: 12px 16px;
         line-height: 32px;
-        font-family: 'mastodon-font-display', sans-serif;
+        font-family: $font-display, sans-serif;
         font-weight: 500;
         font-size: 14px;
 
@@ -473,7 +743,7 @@ $small-breakpoint: 960px;
   .about-short {
     background: darken($ui-base-color, 4%);
     padding: 50px 0 30px;
-    font-family: 'mastodon-font-sans-serif', sans-serif;
+    font-family: $font-sans-serif, sans-serif;
     font-size: 16px;
     font-weight: 400;
     font-size: 16px;
@@ -486,128 +756,6 @@ $small-breakpoint: 960px;
     }
   }
 
-  .information-board {
-    background: darken($ui-base-color, 4%);
-    padding: 20px 0;
-
-    .container-alt {
-      position: relative;
-      padding-right: 280px + 15px;
-    }
-
-    &__sections {
-      display: flex;
-      justify-content: space-between;
-      flex-wrap: wrap;
-    }
-
-    &__section {
-      flex: 1 0 0;
-      font-family: 'mastodon-font-sans-serif', sans-serif;
-      font-size: 16px;
-      line-height: 28px;
-      color: $primary-text-color;
-      text-align: right;
-      padding: 10px 15px;
-
-      span,
-      strong {
-        display: block;
-      }
-
-      span {
-        &:last-child {
-          color: $secondary-text-color;
-        }
-      }
-
-      strong {
-        font-weight: 500;
-        font-size: 32px;
-        line-height: 48px;
-      }
-
-      @media screen and (max-width: $column-breakpoint) {
-        text-align: center;
-      }
-    }
-
-    .panel {
-      position: absolute;
-      width: 280px;
-      box-sizing: border-box;
-      background: darken($ui-base-color, 8%);
-      padding: 20px;
-      padding-top: 10px;
-      border-radius: 4px 4px 0 0;
-      right: 0;
-      bottom: -40px;
-
-      .panel-header {
-        font-family: 'mastodon-font-display', sans-serif;
-        font-size: 14px;
-        line-height: 24px;
-        font-weight: 500;
-        color: $darker-text-color;
-        padding-bottom: 5px;
-        margin-bottom: 15px;
-        border-bottom: 1px solid lighten($ui-base-color, 4%);
-        text-overflow: ellipsis;
-        white-space: nowrap;
-        overflow: hidden;
-
-        a,
-        span {
-          font-weight: 400;
-          color: darken($darker-text-color, 10%);
-        }
-
-        a {
-          text-decoration: none;
-        }
-      }
-    }
-
-    .owner {
-      text-align: center;
-
-      .avatar {
-        width: 80px;
-        height: 80px;
-        margin: 0 auto;
-        margin-bottom: 15px;
-
-        img {
-          display: block;
-          width: 80px;
-          height: 80px;
-          border-radius: 48px;
-        }
-      }
-
-      .name {
-        font-size: 14px;
-
-        a {
-          display: block;
-          color: $primary-text-color;
-          text-decoration: none;
-
-          &:hover {
-            .display_name {
-              text-decoration: underline;
-            }
-          }
-        }
-
-        .username {
-          display: block;
-          color: $darker-text-color;
-        }
-      }
-    }
-  }
-
   &.alternative {
     padding: 10px 0;
 
@@ -642,8 +790,10 @@ $small-breakpoint: 960px;
     border-radius: 4px;
     padding: 25px 40px;
     overflow: hidden;
+    box-sizing: border-box;
 
     .row {
+      width: 100%;
       display: flex;
       flex-direction: row-reverse;
       flex-wrap: wrap;
@@ -660,11 +810,20 @@ $small-breakpoint: 960px;
         flex: 1 0 auto;
         padding: 0 10px;
       }
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        width: 100%;
+        justify-content: space-between;
+      }
     }
 
     .row__mascot {
       flex: 1;
       margin: 10px -50px 0 0;
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        display: none;
+      }
     }
   }
 
@@ -853,7 +1012,7 @@ $small-breakpoint: 960px;
     display: flex;
     -webkit-overflow-scrolling: touch;
     -ms-overflow-style: -ms-autohiding-scrollbar;
-    font-family: 'mastodon-font-sans-serif', sans-serif;
+    font-family: $font-sans-serif, sans-serif;
     font-size: 13px;
     line-height: 18px;
     font-weight: 400;
@@ -923,7 +1082,7 @@ $small-breakpoint: 960px;
     }
 
     @media screen and (max-width: $column-breakpoint) {
-      height: 90vh;
+      display: none;
     }
   }
 
@@ -983,21 +1142,6 @@ $small-breakpoint: 960px;
     }
   }
 
-  .extended-description {
-    padding: 50px 0;
-    font-family: 'mastodon-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;
-    }
-  }
-
   .footer-links {
     padding-bottom: 50px;
     text-align: right;
@@ -1115,6 +1259,20 @@ $small-breakpoint: 960px;
   }
 
   &.tag-page {
+    @media screen and (max-width: $column-breakpoint) {
+      padding: 0;
+
+      .container {
+        padding: 0;
+      }
+
+      #mastodon-timeline {
+        display: flex;
+        height: 100vh;
+        border-radius: 0;
+      }
+    }
+
     .grid {
       @media screen and (min-width: $small-breakpoint) {
         grid-template-columns: 33% 67%;
@@ -1146,24 +1304,17 @@ $small-breakpoint: 960px;
 
     @media screen and (max-width: $column-breakpoint) {
       .grid {
+        grid-gap: 0;
+
         .column-1 {
           grid-column: 1;
-          grid-row: 2;
+          grid-row: 1;
         }
 
         .column-2 {
-          grid-column: 1;
-          grid-row: 1;
+          display: none;
         }
       }
-
-      .brand {
-        margin: 0;
-      }
-
-      .landing-page__features {
-        display: none;
-      }
     }
   }
 }
diff --git a/app/javascript/styles/mastodon/accessibility.scss b/app/javascript/styles/mastodon/accessibility.scss
index 373bcd4ac91e4c20c7d49d2c0a649e9fd6b6b3eb..d33806c8487f5adfaf47d20a9ea3554d5a95ae6b 100644
--- a/app/javascript/styles/mastodon/accessibility.scss
+++ b/app/javascript/styles/mastodon/accessibility.scss
@@ -1,4 +1,4 @@
-$black-emojis: '8ball' 'ant' 'back' 'black_circle' 'black_large_square' 'black_medium_small_square' 'black_medium_square' 'black_nib' 'black_small_square' 'bomb' 'bust_in_silhouette' 'camera' 'camera_with_flash' 'clubs' 'copyright' 'curly_loop' 'currency_exchange' 'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign' 'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'lower_left_fountain_pen' 'on' 'registered' 'soon' 'spades' 'spider' 'tm' 'top' 'waving_black_flag' 'wavy_dash' 'video_game';
+$black-emojis: '8ball' 'ant' 'back' 'black_circle' 'black_heart' 'black_large_square' 'black_medium_small_square' 'black_medium_square' 'black_nib' 'black_small_square' 'bomb' 'bowling' 'bust_in_silhouette' 'busts_in_silhouette' 'camera' 'camera_with_flash' 'clubs' 'copyright' 'curly_loop' 'currency_exchange' 'dark_sunglasses' 'eight_pointed_black_star' 'electric_plug' 'end' 'female-guard' 'film_projector' 'fried_egg' 'gorilla' 'guardsman' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign' 'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'hocho' 'hole' 'joystick' 'kaaba' 'lower_left_ballpoint_pen' 'lower_left_fountain_pen' 'male-guard' 'microphone' 'mortar_board' 'movie_camera' 'musical_score' 'on' 'registered' 'soon' 'spades' 'speaking_head_in_silhouette' 'spider' 'telephone_receiver' 'tm' 'top' 'tophat' 'turkey' 'vhs' 'video_camera' 'video_game' 'water_buffalo' 'waving_black_flag' 'wavy_dash';
 
 %white-emoji-outline {
   filter: drop-shadow(1px 1px 0 $white) drop-shadow(-1px 1px 0 $white) drop-shadow(1px -1px 0 $white) drop-shadow(-1px -1px 0 $white);
diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss
index b4612b063cd5befb7138c77633862bbfa29ef78b..63a5c61b8bfcd919d1cdf0d060b8039d10dc25cd 100644
--- a/app/javascript/styles/mastodon/accounts.scss
+++ b/app/javascript/styles/mastodon/accounts.scss
@@ -1,243 +1,100 @@
 .card {
-  background-color: $base-shadow-color;
-  background-size: cover;
-  background-position: center;
-  border-radius: 4px 4px 0 0;
-  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-  overflow: hidden;
-  position: relative;
-  display: flex;
-
-  &::after {
-    background: rgba(darken($ui-base-color, 8%), 0.5);
+  & > a {
     display: block;
-    content: "";
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 100%;
-    height: 100%;
-    z-index: 1;
-  }
-
-  @media screen and (max-width: 740px) {
-    border-radius: 0;
-    box-shadow: none;
-  }
-
-  .card__illustration {
-    padding: 60px 0;
-    position: relative;
-    flex: 1 1 auto;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-
-  .card__bio {
-    max-width: 260px;
-    flex: 1 1 auto;
-    display: flex;
-    flex-direction: column;
-    justify-content: space-between;
-    background: rgba(darken($ui-base-color, 8%), 0.8);
-    position: relative;
-    z-index: 2;
-  }
-
-  &.compact {
-    padding: 30px 0;
-    border-radius: 4px;
-
-    .avatar {
-      margin-bottom: 0;
+    text-decoration: none;
+    color: inherit;
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
 
-      img {
-        object-fit: cover;
-      }
+    @media screen and (max-width: $no-gap-breakpoint) {
+      box-shadow: none;
     }
-  }
-
-  .name {
-    display: block;
-    font-size: 20px;
-    line-height: 18px * 1.5;
-    color: $primary-text-color;
-    padding: 10px 15px;
-    padding-bottom: 0;
-    font-weight: 500;
-    position: relative;
-    z-index: 2;
-    margin-bottom: 30px;
-    overflow: hidden;
-    text-overflow: ellipsis;
 
-    small {
-      display: block;
-      font-size: 14px;
-      color: $highlight-text-color;
-      font-weight: 400;
-      overflow: hidden;
-      text-overflow: ellipsis;
-
-      .fa {
-        margin-left: 3px;
+    &:hover,
+    &:active,
+    &:focus {
+      .card__bar {
+        background: lighten($ui-base-color, 8%);
       }
     }
   }
 
-  .avatar {
-    width: 120px;
-    margin: 0 auto;
+  &__img {
+    height: 130px;
     position: relative;
-    z-index: 2;
+    background: darken($ui-base-color, 12%);
+    border-radius: 4px 4px 0 0;
 
     img {
-      width: 120px;
-      height: 120px;
-      display: block;
-      border-radius: 120px;
-      box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-    }
-  }
-
-  .roles {
-    margin-bottom: 30px;
-    padding: 0 15px;
-  }
-
-  .details-counters {
-    margin-top: 30px;
-    display: flex;
-    flex-direction: row;
-    width: 100%;
-  }
-
-  .counter {
-    width: 33.3%;
-    box-sizing: border-box;
-    flex: 0 0 auto;
-    color: $darker-text-color;
-    padding: 5px 10px 0;
-    margin-bottom: 10px;
-    border-right: 1px solid lighten($ui-base-color, 4%);
-    cursor: default;
-    text-align: center;
-    position: relative;
-
-    a {
-      display: block;
-    }
-
-    &:last-child {
-      border-right: 0;
-    }
-
-    &::after {
       display: block;
-      content: "";
-      position: absolute;
-      bottom: -10px;
-      left: 0;
       width: 100%;
-      border-bottom: 4px solid $ui-primary-color;
-      opacity: 0.5;
-      transition: all 400ms ease;
-    }
-
-    &.active {
-      &::after {
-        border-bottom: 4px solid $highlight-text-color;
-        opacity: 1;
-      }
-    }
-
-    &:hover {
-      &::after {
-        opacity: 1;
-        transition-duration: 100ms;
-      }
-    }
-
-    a {
-      text-decoration: none;
-      color: inherit;
+      height: 100%;
+      margin: 0;
+      object-fit: cover;
+      border-radius: 4px 4px 0 0;
     }
 
-    .counter-label {
-      font-size: 12px;
-      display: block;
-      margin-bottom: 5px;
+    @media screen and (max-width: 600px) {
+      height: 200px;
     }
 
-    .counter-number {
-      font-weight: 500;
-      font-size: 18px;
-      color: $primary-text-color;
-      font-family: 'mastodon-font-display', sans-serif;
+    @media screen and (max-width: $no-gap-breakpoint) {
+      display: none;
     }
   }
 
-  .bio {
-    font-size: 14px;
-    line-height: 18px;
-    padding: 0 15px;
-    color: $secondary-text-color;
-  }
-
-  @media screen and (max-width: 480px) {
-    display: block;
+  &__bar {
+    position: relative;
+    padding: 15px;
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    background: lighten($ui-base-color, 4%);
+    border-radius: 0 0 4px 4px;
 
-    .card__bio {
-      max-width: none;
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-radius: 0;
     }
 
-    .name,
-    .roles {
-      text-align: center;
-      margin-bottom: 15px;
-    }
+    .avatar {
+      flex: 0 0 auto;
+      width: 48px;
+      height: 48px;
+      padding-top: 2px;
 
-    .bio {
-      margin-bottom: 15px;
+      img {
+        width: 100%;
+        height: 100%;
+        display: block;
+        margin: 0;
+        border-radius: 4px;
+        background: darken($ui-base-color, 8%);
+      }
     }
-  }
-}
 
-.card,
-.account-grid-card {
-  .controls {
-    position: absolute;
-    top: 15px;
-    left: 15px;
-    z-index: 2;
-
-    .icon-button {
-      color: rgba($white, 0.8);
-      text-decoration: none;
-      font-size: 13px;
-      line-height: 13px;
-      font-weight: 500;
+    .display-name {
+      margin-left: 15px;
+      text-align: left;
 
-      .fa {
-        font-weight: 400;
-        margin-right: 5px;
+      strong {
+        font-size: 15px;
+        color: $primary-text-color;
+        font-weight: 500;
+        overflow: hidden;
+        text-overflow: ellipsis;
       }
 
-      &:hover,
-      &:active,
-      &:focus {
-        color: $white;
+      span {
+        display: block;
+        font-size: 14px;
+        color: $darker-text-color;
+        font-weight: 400;
+        overflow: hidden;
+        text-overflow: ellipsis;
       }
     }
   }
 }
 
-.account-grid-card .controls {
-  left: auto;
-  right: 15px;
-}
-
 .pagination {
   padding: 30px 0;
   text-align: center;
@@ -314,289 +171,28 @@
   }
 }
 
-.accounts-grid {
-  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-  background: darken($simple-background-color, 8%);
-  border-radius: 0 0 4px 4px;
-  padding: 20px 5px;
-  padding-bottom: 10px;
-  overflow: hidden;
-  display: flex;
-  flex-wrap: wrap;
-  z-index: 2;
-  position: relative;
-
-  &.empty img {
-    position: absolute;
-    opacity: 0.2;
-    height: 200px;
-    left: 0;
-    bottom: 0;
-    pointer-events: none;
-  }
-
-  @media screen and (max-width: 740px) {
-    border-radius: 0;
-    box-shadow: none;
-  }
-
-  .account-grid-card {
-    box-sizing: border-box;
-    width: 335px;
-    background: $simple-background-color;
-    border-radius: 4px;
-    color: $inverted-text-color;
-    margin: 0 5px 10px;
-    position: relative;
-
-    @media screen and (max-width: 740px) {
-      width: calc(100% - 10px);
-    }
-
-    .account-grid-card__header {
-      overflow: hidden;
-      height: 100px;
-      border-radius: 4px 4px 0 0;
-      background-color: lighten($inverted-text-color, 4%);
-      background-size: cover;
-      background-position: center;
-      position: relative;
-
-      &::after {
-        background: rgba(darken($ui-base-color, 8%), 0.5);
-        display: block;
-        content: "";
-        position: absolute;
-        left: 0;
-        top: 0;
-        width: 100%;
-        height: 100%;
-        z-index: 1;
-      }
-    }
-
-    .account-grid-card__avatar {
-      box-sizing: border-box;
-      padding: 15px;
-      position: absolute;
-      z-index: 2;
-      top: 100px - (40px + 2px);
-      left: -2px;
-    }
-
-    .avatar {
-      width: 80px;
-      height: 80px;
-
-      img {
-        display: block;
-        width: 80px;
-        height: 80px;
-        border-radius: 80px;
-        border: 2px solid $simple-background-color;
-        background: $simple-background-color;
-      }
-    }
-
-    .name {
-      padding: 15px;
-      padding-top: 10px;
-      padding-left: 15px + 80px + 15px;
-
-      a {
-        display: block;
-        color: $inverted-text-color;
-        text-decoration: none;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        font-weight: 500;
-
-        &:hover {
-          .display_name {
-            text-decoration: underline;
-          }
-        }
-      }
-    }
-
-    .display_name {
-      font-size: 16px;
-      display: block;
-      text-overflow: ellipsis;
-      overflow: hidden;
-    }
-
-    .username {
-      color: $lighter-text-color;
-      font-size: 14px;
-      font-weight: 400;
-    }
-
-    .account__header__content {
-      padding: 10px 15px;
-      padding-top: 15px;
-      color: $lighter-text-color;
-      word-wrap: break-word;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      height: 5.5em;
-      position: relative;
-
-      &::after {
-        display: block;
-        content: "";
-        width: 100%;
-        height: 100px;
-        position: absolute;
-        bottom: 0;
-        background: linear-gradient(to bottom, rgba($simple-background-color, 0.01) 0%, rgba($simple-background-color, 1) 100%);
-        left: 0;
-        border-radius: 0 0 4px 4px;
-        pointer-events: none;
-      }
-    }
-  }
-}
-
 .nothing-here {
-  width: 100%;
-  display: block;
+  background: $ui-base-color;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
   color: $light-text-color;
   font-size: 14px;
   font-weight: 500;
   text-align: center;
-  padding: 130px 0;
-  padding-top: 125px;
-  margin: 0 auto;
+  display: flex;
+  justify-content: center;
+  align-items: center;
   cursor: default;
-}
-
-.account-card {
   border-radius: 4px;
-  text-align: left;
-  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-  background: $simple-background-color;
-
-  &__header {
-    background: $base-shadow-color;
-    background-size: cover;
-    background-position: center center;
-    height: 90px;
-    border-radius: 4px 4px 0 0;
-  }
-
-  & > .detailed-status__display-name {
-    display: block;
-    overflow: hidden;
-    display: flex;
-    align-items: center;
-    padding: 10px;
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-
-    & > div:first-child {
-      flex: 0 0 auto;
-      margin-right: 10px;
-      width: 48px;
-      height: 48px;
-    }
-
-    .avatar {
-      display: block;
-      border-radius: 4px;
-      margin: 0;
-    }
-
-    .display-name {
-      flex: 1 0 auto;
-      display: block;
-      max-width: 100%;
-      overflow: hidden;
-      white-space: nowrap;
-      text-overflow: ellipsis;
-      cursor: default;
-
-      & > .detailed-status__display-name {
-        margin-bottom: 0;
-      }
-
-      strong {
-        font-weight: 500;
-        color: $ui-base-color;
+  padding: 20px;
+  min-height: 30vh;
 
-        @each $lang in $cjk-langs {
-          &:lang(#{$lang}) {
-            font-weight: 700;
-          }
-        }
-      }
-
-      span {
-        font-size: 14px;
-        color: $light-text-color;
-      }
-    }
-
-    &:hover {
-      .display-name {
-        strong {
-          text-decoration: none;
-        }
-      }
-    }
+  &--under-tabs {
+    border-radius: 0 0 4px 4px;
   }
 
-  .counter {
+  &--flexible {
     box-sizing: border-box;
-    flex: 0 0 auto;
-    color: $light-text-color;
-    padding: 0 10px;
-    cursor: default;
-    text-align: center;
-    position: relative;
-    line-height: 24px;
-
-    .counter-label {
-      font-size: 12px;
-      display: block;
-      text-transform: uppercase;
-    }
-
-    .counter-number {
-      font-weight: 500;
-      font-size: 16px;
-      color: $inverted-text-color;
-      font-family: 'mastodon-font-display', sans-serif;
-    }
-  }
-}
-
-.activity-stream-tabs {
-  background: $simple-background-color;
-  border-bottom: 1px solid $ui-secondary-color;
-  position: relative;
-  z-index: 2;
-
-  a {
-    display: inline-block;
-    padding: 15px;
-    text-decoration: none;
-    color: $highlight-text-color;
-    text-transform: uppercase;
-    font-weight: 500;
-
-    &:hover,
-    &:active,
-    &:focus {
-      color: lighten($highlight-text-color, 8%);
-    }
-
-    &.active {
-      color: $inverted-text-color;
-      cursor: default;
-    }
+    min-height: 100%;
   }
 }
 
@@ -629,14 +225,14 @@
   padding: 0;
   margin: 15px -15px -15px;
   border: 0 none;
-  border-top: 1px solid lighten($ui-base-color, 4%);
-  border-bottom: 1px solid lighten($ui-base-color, 4%);
+  border-top: 1px solid lighten($ui-base-color, 12%);
+  border-bottom: 1px solid lighten($ui-base-color, 12%);
   font-size: 14px;
   line-height: 20px;
 
   dl {
     display: flex;
-    border-bottom: 1px solid lighten($ui-base-color, 4%);
+    border-bottom: 1px solid lighten($ui-base-color, 12%);
   }
 
   dt,
@@ -674,6 +270,20 @@
     }
   }
 
+  .verified {
+    border: 1px solid rgba($valid-value-color, 0.5);
+    background: rgba($valid-value-color, 0.25);
+
+    a {
+      color: $valid-value-color;
+      font-weight: 500;
+    }
+
+    &__mark {
+      color: $valid-value-color;
+    }
+  }
+
   dl:last-child {
     border-bottom: 0;
   }
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index 560b11ddf4eb2132cf423c6a88b163ccbf0e11a0..177f8145fa86dfce7324cfee6096edf0b1c639b7 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -1,10 +1,14 @@
+$no-columns-breakpoint: 600px;
+$sidebar-width: 240px;
+$content-width: 840px;
+
 .admin-wrapper {
   display: flex;
   justify-content: center;
   height: 100%;
 
   .sidebar-wrapper {
-    flex: 1;
+    flex: 1 1 $sidebar-width;
     height: 100%;
     background: $ui-base-color;
     display: flex;
@@ -12,7 +16,7 @@
   }
 
   .sidebar {
-    width: 240px;
+    width: $sidebar-width;
     height: 100%;
     padding: 0;
     overflow-y: auto;
@@ -24,12 +28,22 @@
       height: 100px;
     }
 
+    @media screen and (max-width: $no-columns-breakpoint) {
+      & > a:first-child {
+        display: none;
+      }
+    }
+
     ul {
       list-style: none;
       border-radius: 4px 0 0 4px;
       overflow: hidden;
       margin-bottom: 20px;
 
+      @media screen and (max-width: $no-columns-breakpoint) {
+        margin-bottom: 0;
+      }
+
       a {
         display: block;
         padding: 15px;
@@ -62,38 +76,50 @@
         a {
           border: 0;
           padding: 15px 35px;
+        }
+      }
 
-          &.selected {
-            color: $primary-text-color;
-            background-color: $ui-highlight-color;
-            border-bottom: 0;
-            border-radius: 0;
+      .simple-navigation-active-leaf a {
+        color: $primary-text-color;
+        background-color: $ui-highlight-color;
+        border-bottom: 0;
+        border-radius: 0;
 
-            &:hover {
-              background-color: lighten($ui-highlight-color, 5%);
-            }
-          }
+        &:hover {
+          background-color: lighten($ui-highlight-color, 5%);
         }
       }
     }
+
+    & > ul > .simple-navigation-active-leaf a {
+      border-radius: 4px 0 0 4px;
+    }
   }
 
   .content-wrapper {
-    flex: 2;
+    flex: 2 1 $content-width;
     overflow: auto;
   }
 
   .content {
-    max-width: 700px;
+    max-width: $content-width;
     padding: 20px 15px;
     padding-top: 60px;
     padding-left: 25px;
 
+    @media screen and (max-width: $no-columns-breakpoint) {
+      max-width: none;
+      padding: 15px;
+      padding-top: 30px;
+    }
+
     h2 {
       color: $secondary-text-color;
       font-size: 24px;
       line-height: 28px;
       font-weight: 400;
+      padding-bottom: 40px;
+      border-bottom: 1px solid lighten($ui-base-color, 8%);
       margin-bottom: 40px;
     }
 
@@ -108,7 +134,7 @@
     h4 {
       text-transform: uppercase;
       font-size: 13px;
-      font-weight: 500;
+      font-weight: 700;
       color: $darker-text-color;
       padding-bottom: 8px;
       margin-bottom: 8px;
@@ -122,6 +148,25 @@
       font-weight: 400;
     }
 
+    .fields-group h6 {
+      color: $primary-text-color;
+      font-weight: 500;
+    }
+
+    .directory__tag a {
+      box-shadow: none;
+    }
+
+    .directory__tag h4 {
+      font-size: 18px;
+      font-weight: 700;
+      color: $primary-text-color;
+      text-transform: none;
+      padding-bottom: 0;
+      margin-bottom: 0;
+      border-bottom: none;
+    }
+
     & > p {
       font-size: 14px;
       line-height: 18px;
@@ -165,32 +210,14 @@
       color: $valid-value-color;
       font-weight: 500;
     }
-  }
-
-  .simple_form {
-    max-width: 400px;
 
-    &.edit_user,
-    &.new_form_admin_settings,
-    &.new_form_two_factor_confirmation,
-    &.new_form_delete_confirmation,
-    &.new_import,
-    &.new_domain_block,
-    &.edit_domain_block {
-      max-width: none;
-    }
-
-    .form_two_factor_confirmation_code,
-    .form_delete_confirmation_password {
-      max-width: 400px;
-    }
-
-    .actions {
-      max-width: 400px;
+    .negative-hint {
+      color: $error-value-color;
+      font-weight: 500;
     }
   }
 
-  @media screen and (max-width: 600px) {
+  @media screen and (max-width: $no-columns-breakpoint) {
     display: block;
     overflow-y: auto;
     -webkit-overflow-scrolling: touch;
@@ -204,16 +231,8 @@
 
     .sidebar {
       width: 100%;
-      padding: 10px 0;
+      padding: 0;
       height: auto;
-
-      .logo {
-        margin: 20px auto;
-      }
-    }
-
-    .content {
-      padding-top: 20px;
     }
   }
 }
@@ -429,7 +448,7 @@
     border-radius: 0 0 4px 4px;
     padding: 10px;
     color: $darker-text-color;
-    font-family: 'mastodon-font-monospace', monospace;
+    font-family: $font-monospace, monospace;
     font-size: 12px;
     word-wrap: break-word;
     min-height: 20px;
@@ -539,6 +558,10 @@ a.name-tag,
     border-left-color: lighten($error-red, 12%);
   }
 
+  &.warning {
+    border-left-color: $gold-star;
+  }
+
   &__bubble {
     padding: 16px;
     padding-left: 14px;
@@ -562,3 +585,102 @@ a.name-tag,
     color: $dark-text-color;
   }
 }
+
+.report-card {
+  background: $ui-base-color;
+  border-radius: 4px;
+  margin-bottom: 20px;
+
+  &__profile {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 15px;
+
+    .account {
+      padding: 0;
+      border: 0;
+
+      &__avatar-wrapper {
+        margin-left: 0;
+      }
+    }
+
+    &__stats {
+      flex: 0 0 auto;
+      font-weight: 500;
+      color: $darker-text-color;
+      text-transform: uppercase;
+      text-align: right;
+
+      a {
+        color: inherit;
+        text-decoration: none;
+
+        &:focus,
+        &:hover,
+        &:active {
+          color: lighten($darker-text-color, 8%);
+        }
+      }
+
+      .red {
+        color: $error-value-color;
+      }
+    }
+  }
+
+  &__summary {
+    &__item {
+      display: flex;
+      justify-content: flex-start;
+      border-top: 1px solid darken($ui-base-color, 4%);
+
+      &:hover {
+        background: lighten($ui-base-color, 2%);
+      }
+
+      &__reported-by,
+      &__assigned {
+        padding: 15px;
+        flex: 0 0 auto;
+        box-sizing: border-box;
+        width: 150px;
+        color: $darker-text-color;
+
+        &,
+        .username {
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+        }
+      }
+
+      &__content {
+        flex: 1 1 auto;
+        max-width: calc(100% - 300px);
+
+        &__icon {
+          color: $dark-text-color;
+          margin-right: 4px;
+          font-weight: 500;
+        }
+      }
+
+      &__content a {
+        display: block;
+        box-sizing: border-box;
+        width: 100%;
+        padding: 15px;
+        text-decoration: none;
+        color: $darker-text-color;
+      }
+    }
+  }
+}
+
+.one-line {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss
index c52e069be6720347882f35f5dc2c5189e7f1104b..746def6251c14349b6b5227c38ceb4f1ec7c6fc2 100644
--- a/app/javascript/styles/mastodon/basics.scss
+++ b/app/javascript/styles/mastodon/basics.scss
@@ -1,13 +1,17 @@
+@function hex-color($color) {
+  @if type-of($color) == 'color' {
+    $color: str-slice(ie-hex-str($color), 4);
+  }
+  @return '%23' + unquote($color)
+}
+
 body {
-  font-family: 'mastodon-font-sans-serif', sans-serif;
-  background: $ui-base-color;
-  background-size: cover;
-  background-attachment: fixed;
+  font-family: $font-sans-serif, sans-serif;
+  background: darken($ui-base-color, 8%);
   font-size: 13px;
   line-height: 18px;
   font-weight: 400;
   color: $primary-text-color;
-  padding-bottom: 20px;
   text-rendering: optimizelegibility;
   font-feature-settings: "kern";
   text-size-adjust: none;
@@ -25,8 +29,8 @@ body {
     // Fira Sans => Firefox OS
     // Droid Sans => Older Androids (<4.0)
     // Helvetica Neue => Older macOS <10.11
-    // mastodon-font-sans-serif => web-font (Roboto) fallback and newer Androids (>=4.0)
-    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", mastodon-font-sans-serif, sans-serif;
+    // $font-sans-serif => web-font (Roboto) fallback and newer Androids (>=4.0)
+    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", $font-sans-serif, sans-serif;
   }
 
   &.app-body {
@@ -35,16 +39,24 @@ body {
     height: 100%;
     padding: 0;
     background: $ui-base-color;
+
+    &.with-modals--active {
+      overflow-y: hidden;
+    }
   }
 
-  &.about-body {
-    background: darken($ui-base-color, 8%);
-    padding-bottom: 0;
+  &.lighter {
+    background: $ui-base-color;
   }
 
-  &.tag-body {
-    background: darken($ui-base-color, 8%);
-    padding-bottom: 0;
+  &.with-modals {
+    overflow-x: hidden;
+    overflow-y: scroll;
+
+    &--active {
+      overflow-y: hidden;
+      margin-right: 13px;
+    }
   }
 
   &.player {
@@ -52,7 +64,7 @@ body {
   }
 
   &.embed {
-    background: transparent;
+    background: lighten($ui-base-color, 4%);
     margin: 0;
     padding-bottom: 0;
 
diff --git a/app/javascript/styles/mastodon/boost.scss b/app/javascript/styles/mastodon/boost.scss
index 8e11cb5960caed491e3fa83de9a1e762a69ff367..5a6d6ae406c4610faf56bd1bcbba343f7c67b23a 100644
--- a/app/javascript/styles/mastodon/boost.scss
+++ b/app/javascript/styles/mastodon/boost.scss
@@ -1,10 +1,3 @@
-@function hex-color($color) {
-  @if type-of($color) == 'color' {
-    $color: str-slice(ie-hex-str($color), 4);
-  }
-  @return '%23' + unquote($color)
-}
-
 button.icon-button i.fa-retweet {
   background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='209'><path d='M4.97 3.16c-.1.03-.17.1-.22.18L.8 8.24c-.2.3.03.78.4.8H3.6v2.68c0 4.26-.55 3.62 3.66 3.62h7.66l-2.3-2.84c-.03-.02-.03-.04-.05-.06H7.27c-.44 0-.72-.3-.72-.72v-2.7h2.5c.37.03.63-.48.4-.77L5.5 3.35c-.12-.17-.34-.25-.53-.2zm12.16.43c-.55-.02-1.32.02-2.4.02H7.1l2.32 2.85.03.06h5.25c.42 0 .72.28.72.72v2.7h-2.5c-.36.02-.56.54-.3.8l3.92 4.9c.18.25.6.25.78 0l3.94-4.9c.26-.28 0-.83-.37-.8H18.4v-2.7c0-3.15.4-3.62-1.25-3.66z' fill='#{hex-color($action-button-color)}' stroke-width='0'/><path d='M7.78 19.66c-.24.02-.44.25-.44.5v2.46h-.06c-1.08 0-1.86-.03-2.4-.03-1.64 0-1.25.43-1.25 3.65v4.47c0 4.26-.56 3.62 3.65 3.62H8.5l-1.3-1.06c-.1-.08-.18-.2-.2-.3-.02-.17.06-.35.2-.45l1.33-1.1H7.28c-.44 0-.72-.3-.72-.7v-4.48c0-.44.28-.72.72-.72h.06v2.5c0 .38.54.63.82.38l4.9-3.93c.25-.18.25-.6 0-.78l-4.9-3.92c-.1-.1-.24-.14-.38-.12zm9.34 2.93c-.54-.02-1.3.02-2.4.02h-1.25l1.3 1.07c.1.07.18.2.2.33.02.16-.06.3-.2.4l-1.33 1.1h1.28c.42 0 .72.28.72.72v4.47c0 .42-.3.72-.72.72h-.1v-2.47c0-.3-.3-.53-.6-.47-.07 0-.14.05-.2.1l-4.9 3.93c-.26.18-.26.6 0 .78l4.9 3.92c.27.25.82 0 .8-.38v-2.5h.1c4.27 0 3.65.67 3.65-3.62v-4.47c0-3.15.4-3.62-1.25-3.66zM10.34 38.66c-.24.02-.44.25-.43.5v2.47H7.3c-1.08 0-1.86-.04-2.4-.04-1.64 0-1.25.43-1.25 3.65v4.47c0 3.66-.23 3.7 2.34 3.66l-1.34-1.1c-.1-.08-.18-.2-.2-.3 0-.17.07-.35.2-.45l1.96-1.6c-.03-.06-.04-.13-.04-.2v-4.48c0-.44.28-.72.72-.72H9.9v2.5c0 .36.5.6.8.38l4.93-3.93c.24-.18.24-.6 0-.78l-4.94-3.92c-.1-.08-.23-.13-.36-.12zm5.63 2.93l1.34 1.1c.1.07.18.2.2.33.02.16-.03.3-.16.4l-1.96 1.6c.02.07.06.13.06.22v4.47c0 .42-.3.72-.72.72h-2.66v-2.47c0-.3-.3-.53-.6-.47-.06.02-.12.05-.18.1l-4.94 3.93c-.24.18-.24.6 0 .78l4.94 3.92c.28.22.78-.02.78-.38v-2.5h2.66c4.27 0 3.65.67 3.65-3.62v-4.47c0-3.66.34-3.7-2.4-3.66zM13.06 57.66c-.23.03-.4.26-.4.5v2.47H7.28c-1.08 0-1.86-.04-2.4-.04-1.64 0-1.25.43-1.25 3.65v4.87l2.93-2.37v-2.5c0-.44.28-.72.72-.72h5.38v2.5c0 .36.5.6.78.38l4.94-3.93c.24-.18.24-.6 0-.78l-4.94-3.92c-.1-.1-.24-.14-.38-.12zm5.3 6.15l-2.92 2.4v2.52c0 .42-.3.72-.72.72h-5.4v-2.47c0-.3-.32-.53-.6-.47-.07.02-.13.05-.2.1L3.6 70.52c-.25.18-.25.6 0 .78l4.93 3.92c.28.22.78-.02.78-.38v-2.5h5.42c4.27 0 3.65.67 3.65-3.62v-4.47-.44zM19.25 78.8c-.1.03-.2.1-.28.17l-.9.9c-.44-.3-1.36-.25-3.35-.25H7.28c-1.08 0-1.86-.03-2.4-.03-1.64 0-1.25.43-1.25 3.65v.7l2.93.3v-1c0-.44.28-.72.72-.72h7.44c.2 0 .37.08.5.2l-1.8 1.8c-.25.26-.08.76.27.8l6.27.7c.28.03.56-.25.53-.53l-.7-6.25c0-.27-.3-.48-.55-.44zm-17.2 6.1c-.2.07-.36.3-.33.54l.7 6.25c.02.36.58.55.83.27l.8-.8c.02 0 .04-.02.04 0 .46.24 1.37.17 3.18.17h7.44c4.27 0 3.65.67 3.65-3.62v-.75l-2.93-.3v1.05c0 .42-.3.72-.72.72H7.28c-.15 0-.3-.03-.4-.1L8.8 86.4c.3-.24.1-.8-.27-.84l-6.28-.65h-.2zM4.88 98.6c-1.33 0-1.34.48-1.3 2.3l1.14-1.37c.08-.1.22-.17.34-.2.16 0 .34.08.44.2l1.66 2.03c.04 0 .07-.03.12-.03h7.44c.34 0 .57.2.65.5h-2.43c-.34.05-.53.52-.3.78l3.92 4.95c.18.24.6.24.78 0l3.94-4.94c.22-.27-.02-.76-.37-.77H18.4c.02-3.9.6-3.4-3.66-3.4H7.28c-1.08 0-1.86-.04-2.4-.04zm.15 2.46c-.1.03-.2.1-.28.2l-3.94 4.9c-.2.28.03.77.4.78H3.6c-.02 3.94-.45 3.4 3.66 3.4h7.44c3.65 0 3.74.3 3.7-2.25l-1.1 1.34c-.1.1-.2.17-.32.2-.16 0-.34-.08-.44-.2l-1.65-2.03c-.06.02-.1.04-.18.04H7.28c-.35 0-.57-.2-.66-.5h2.44c.37 0 .63-.5.4-.78l-3.96-4.9c-.1-.15-.3-.23-.47-.2zM4.88 117.6c-1.16 0-1.3.3-1.3 1.56l1.14-1.38c.08-.1.22-.14.34-.16.16 0 .34.04.44.16l2.22 2.75h7c.42 0 .72.28.72.72v.53h-2.6c-.3.1-.43.54-.2.78l3.92 4.9c.18.25.6.25.78 0l3.94-4.9c.22-.28-.02-.77-.37-.78H18.4v-.53c0-4.2.72-3.63-3.66-3.63H7.28c-1.08 0-1.86-.03-2.4-.03zm.1 1.74c-.1.03-.17.1-.23.16L.8 124.44c-.2.28.03.77.4.78H3.6v.5c0 4.26-.55 3.62 3.66 3.62h7.44c1.03 0 1.74.02 2.28 0-.16.02-.34-.03-.44-.15l-2.22-2.76H7.28c-.44 0-.72-.3-.72-.72v-.5h2.5c.37.02.63-.5.4-.78L5.5 119.5c-.12-.15-.34-.22-.53-.16zm12.02 10c1.2-.02 1.4-.25 1.4-1.53l-1.1 1.36c-.07.1-.17.17-.3.18zM5.94 136.6l2.37 2.93h6.42c.42 0 .72.28.72.72v1.25h-2.6c-.3.1-.43.54-.2.78l3.92 4.9c.18.25.6.25.78 0l3.94-4.9c.22-.28-.02-.77-.37-.78H18.4v-1.25c0-4.2.72-3.63-3.66-3.63H7.28c-.6 0-.92-.02-1.34-.03zm-1.72.06c-.4.08-.54.3-.6.75l.6-.74zm.84.93c-.12 0-.24.08-.3.18l-3.95 4.9c-.24.3 0 .83.4.82H3.6v1.22c0 4.26-.55 3.62 3.66 3.62h7.44c.63 0 .97.02 1.4.03l-2.37-2.93H7.28c-.44 0-.72-.3-.72-.72v-1.22h2.5c.4.04.67-.53.4-.8l-3.96-4.92c-.1-.13-.27-.2-.44-.2zm13.28 10.03l-.56.7c.36-.07.5-.3.56-.7zM17.13 155.6c-.55-.02-1.32.03-2.4.03h-8.2l2.38 2.9h5.82c.42 0 .72.28.72.72v1.97H12.9c-.32.06-.48.52-.28.78l3.94 4.94c.2.23.6.22.78-.03l3.94-4.9c.22-.28-.02-.77-.37-.78H18.4v-1.97c0-3.15.4-3.62-1.25-3.66zm-12.1.28c-.1.02-.2.1-.28.18l-3.94 4.9c-.2.3.03.78.4.8H3.6v1.96c0 4.26-.55 3.62 3.66 3.62h8.24l-2.36-2.9H7.28c-.44 0-.72-.3-.72-.72v-1.97h2.5c.37.02.63-.5.4-.78l-3.96-4.9c-.1-.15-.3-.22-.47-.2zM5.13 174.5c-.15 0-.3.07-.38.2L.8 179.6c-.24.27 0 .82.4.8H3.6v2.32c0 4.26-.55 3.62 3.66 3.62h7.94l-2.35-2.9h-5.6c-.43 0-.7-.3-.7-.72v-2.3h2.5c.38.03.66-.54.4-.83l-3.97-4.9c-.1-.13-.23-.2-.38-.2zm12 .1c-.55-.02-1.32.03-2.4.03H6.83l2.35 2.9h5.52c.42 0 .72.28.72.72v2.34h-2.6c-.3.1-.43.53-.2.78l3.92 4.9c.18.24.6.24.78 0l3.94-4.9c.22-.3-.02-.78-.37-.8H18.4v-2.33c0-3.15.4-3.62-1.25-3.66zM4.97 193.16c-.1.03-.17.1-.22.18l-3.94 4.9c-.2.3.03.78.4.8H3.6v2.68c0 4.26-.55 3.62 3.66 3.62h7.66l-2.3-2.84c-.03-.02-.03-.04-.05-.06H7.27c-.44 0-.72-.3-.72-.72v-2.7h2.5c.37.03.63-.48.4-.77l-3.96-4.9c-.12-.17-.34-.25-.53-.2zm12.16.43c-.55-.02-1.32.03-2.4.03H7.1l2.32 2.84.03.06h5.25c.42 0 .72.28.72.72v2.7h-2.5c-.36.02-.56.54-.3.8l3.92 4.9c.18.25.6.25.78 0l3.94-4.9c.26-.28 0-.83-.37-.8H18.4v-2.7c0-3.15.4-3.62-1.25-3.66z' fill='#{hex-color($highlight-text-color)}' stroke-width='0'/></svg>");
 
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 5fa73d58a207d54485432c075c2c0a03956ed0da..10e094648197e6ef05b9483934d717e439ef729e 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -35,6 +35,17 @@
     transition: all 200ms ease-out;
   }
 
+  &--destructive {
+    transition: none;
+
+    &:active,
+    &:focus,
+    &:hover {
+      background-color: $error-red;
+      transition: none;
+    }
+  }
+
   &:disabled {
     background-color: $ui-primary-color;
     cursor: default;
@@ -219,7 +230,6 @@
 
 .dropdown-menu {
   position: absolute;
-  transform-origin: 50% 0;
 }
 
 .invisible {
@@ -542,7 +552,7 @@
 
       .character-counter {
         cursor: default;
-        font-family: 'mastodon-font-sans-serif', sans-serif;
+        font-family: $font-sans-serif, sans-serif;
         font-size: 14px;
         font-weight: 600;
         color: $lighter-text-color;
@@ -621,13 +631,16 @@
 
 .status__content,
 .reply-indicator__content {
+  position: relative;
   font-size: 15px;
   line-height: 20px;
   word-wrap: break-word;
   font-weight: 400;
   overflow: hidden;
+  text-overflow: ellipsis;
   white-space: pre-wrap;
   padding-top: 2px;
+  color: $primary-text-color;
 
   &:focus {
     outline: 0;
@@ -710,6 +723,26 @@
   }
 }
 
+.status__content.status__content--collapsed {
+  max-height: 20px * 15; // 15 lines is roughly above 500 characters
+}
+
+.status__content__read-more-button {
+  display: block;
+  font-size: 15px;
+  line-height: 20px;
+  color: lighten($ui-highlight-color, 8%);
+  border: 0;
+  background: transparent;
+  padding: 0;
+  padding-top: 8px;
+
+  &:hover,
+  &:active {
+    text-decoration: underline;
+  }
+}
+
 .status__content__spoiler-link {
   display: inline-block;
   border-radius: 2px;
@@ -768,7 +801,7 @@
   padding: 8px 10px;
   padding-left: 68px;
   position: relative;
-  min-height: 48px;
+  min-height: 54px;
   border-bottom: 1px solid lighten($ui-base-color, 8%);
   cursor: default;
 
@@ -790,8 +823,9 @@
     margin-top: 8px;
   }
 
-  &.status-direct {
+  &.status-direct:not(.read) {
     background: lighten($ui-base-color, 8%);
+    border-bottom-color: lighten($ui-base-color, 12%);
   }
 
   &.light {
@@ -842,7 +876,8 @@
   }
 }
 
-.status__relative-time {
+.status__relative-time,
+.notification__relative_time {
   color: $dark-text-color;
   float: right;
   font-size: 14px;
@@ -921,15 +956,31 @@
   align-items: center;
   display: flex;
   margin-top: 8px;
+
+  &__counter {
+    display: inline-flex;
+    margin-right: 11px;
+    align-items: center;
+
+    .status__action-bar-button {
+      margin-right: 4px;
+    }
+
+    &__label {
+      display: inline-block;
+      width: 14px;
+      font-size: 12px;
+      font-weight: 500;
+      color: $action-button-color;
+    }
+  }
 }
 
 .status__action-bar-button {
-  float: left;
   margin-right: 18px;
 }
 
 .status__action-bar-dropdown {
-  float: left;
   height: 23.15px;
   width: 23.15px;
 }
@@ -946,6 +997,18 @@
   background: lighten($ui-base-color, 4%);
   padding: 14px 10px;
 
+  &--flex {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    align-items: flex-start;
+
+    .status__content,
+    .detailed-status__meta {
+      flex: 100%;
+    }
+  }
+
   .status__content {
     font-size: 19px;
     line-height: 24px;
@@ -1071,6 +1134,18 @@
     vertical-align: middle;
     margin-right: 5px;
   }
+
+  &-composite {
+    @include avatar-radius();
+    overflow: hidden;
+
+    & > div {
+      @include avatar-radius();
+      float: left;
+      position: relative;
+      box-sizing: border-box;
+    }
+  }
 }
 
 a .account__avatar {
@@ -1224,7 +1299,6 @@ a .account__avatar {
 }
 
 .account__action-bar-dropdown {
-  flex: 0 1 calc(50% - 140px);
   padding: 10px;
 
   .icon-button {
@@ -1256,9 +1330,14 @@ a .account__avatar {
 .account__action-bar__tab {
   text-decoration: none;
   overflow: hidden;
-  flex: 0 1 80px;
+  flex: 0 1 100%;
   border-right: 1px solid lighten($ui-base-color, 8%);
-  padding: 10px 5px;
+  padding: 10px 0;
+  border-bottom: 4px solid transparent;
+
+  &.active {
+    border-bottom: 4px solid $ui-highlight-color;
+  }
 
   & > span {
     display: block;
@@ -1411,6 +1490,7 @@ a.account__display-name {
   cursor: default;
   color: $darker-text-color;
   font-size: 15px;
+  line-height: 22px;
   position: relative;
 
   .fa {
@@ -1418,7 +1498,7 @@ a.account__display-name {
   }
 
   > span {
-    display: block;
+    display: inline;
     overflow: hidden;
     text-overflow: ellipsis;
   }
@@ -1448,6 +1528,10 @@ a.account__display-name {
   }
 }
 
+.notification__relative_time {
+  float: right;
+}
+
 .display-name {
   display: block;
   max-width: 100%;
@@ -1478,6 +1562,7 @@ a.account__display-name {
   display: flex;
   align-items: center;
   justify-content: center;
+  flex-direction: column;
 
   .image-loader__preview-canvas {
     max-width: $media-modal-media-max-width;
@@ -1486,8 +1571,8 @@ a.account__display-name {
     object-fit: contain;
   }
 
-  &.image-loader--loading .image-loader__preview-canvas {
-    filter: blur(2px);
+  .loading-bar {
+    position: relative;
   }
 
   &.image-loader--amorphous .image-loader__preview-canvas {
@@ -1590,10 +1675,27 @@ a.account__display-name {
   padding: 4px 0;
   border-radius: 4px;
   box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
+  z-index: 9999;
 
   ul {
     list-style: none;
   }
+
+  &.left {
+    transform-origin: 100% 50%;
+  }
+
+  &.top {
+    transform-origin: 50% 100%;
+  }
+
+  &.bottom {
+    transform-origin: 50% 0;
+  }
+
+  &.right {
+    transform-origin: 0 50%;
+  }
 }
 
 .dropdown-menu__arrow {
@@ -1611,14 +1713,14 @@ a.account__display-name {
 
   &.top {
     bottom: -5px;
-    margin-left: -13px;
+    margin-left: -7px;
     border-width: 5px 7px 0;
     border-top-color: $ui-secondary-color;
   }
 
   &.bottom {
     top: -5px;
-    margin-left: -13px;
+    margin-left: -7px;
     border-width: 0 7px 5px;
     border-bottom-color: $ui-secondary-color;
   }
@@ -1751,7 +1853,7 @@ a.account__display-name {
 }
 
 .column {
-  width: 330px;
+  width: 350px;
   position: relative;
   box-sizing: border-box;
   display: flex;
@@ -1996,6 +2098,17 @@ a.account__display-name {
   @supports(display: grid) { // hack to fix Chrome <57
     contain: strict;
   }
+
+  &--flex {
+    display: flex;
+    flex-direction: column;
+  }
+
+  &__append {
+    flex: 1 1 auto;
+    position: relative;
+    min-height: 120px;
+  }
 }
 
 .scrollable.fullscreen {
@@ -2010,6 +2123,7 @@ a.account__display-name {
   cursor: pointer;
   flex: 0 0 auto;
   font-size: 16px;
+  line-height: inherit;
   border: 0;
   text-align: unset;
   padding: 15px;
@@ -2223,28 +2337,6 @@ a.account__display-name {
 .getting-started {
   color: $dark-text-color;
 
-  p {
-    color: $dark-text-color;
-    font-size: 13px;
-    margin-bottom: 20px;
-
-    a {
-      color: $dark-text-color;
-      text-decoration: underline;
-    }
-  }
-
-  a {
-    text-decoration: none;
-    color: $darker-text-color;
-
-    &:hover,
-    &:focus,
-    &:active {
-      text-decoration: underline;
-    }
-  }
-
   &__footer {
     flex: 0 0 auto;
     padding: 10px;
@@ -2257,6 +2349,28 @@ a.account__display-name {
     ul li {
       display: inline;
     }
+
+    p {
+      color: $dark-text-color;
+      font-size: 13px;
+      margin-bottom: 20px;
+
+      a {
+        color: $dark-text-color;
+        text-decoration: underline;
+      }
+    }
+
+    a {
+      text-decoration: none;
+      color: $darker-text-color;
+
+      &:hover,
+      &:focus,
+      &:active {
+        text-decoration: underline;
+      }
+    }
   }
 
   &__trends {
@@ -2464,12 +2578,24 @@ a.status-card {
   display: block;
   margin-top: 5px;
   font-size: 13px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 
 .status-card__image {
   flex: 0 0 100px;
   background: lighten($ui-base-color, 8%);
   position: relative;
+
+  & > .fa {
+    font-size: 21px;
+    position: absolute;
+    transform-origin: 50% 50%;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+  }
 }
 
 .status-card.horizontal {
@@ -2488,6 +2614,31 @@ a.status-card {
   }
 }
 
+.status-card.compact {
+  border-color: lighten($ui-base-color, 4%);
+
+  &.interactive {
+    border: 0;
+  }
+
+  .status-card__content {
+    padding: 8px;
+    padding-top: 10px;
+  }
+
+  .status-card__title {
+    white-space: nowrap;
+  }
+
+  .status-card__image {
+    flex: 0 0 60px;
+  }
+}
+
+a.status-card.compact:hover {
+  background-color: lighten($ui-base-color, 4%);
+}
+
 .status-card__image-image {
   border-radius: 4px 0 0 4px;
   display: block;
@@ -2759,7 +2910,6 @@ a.status-card {
     transform: translateX(-50%);
     margin: 82px 0 0 50%;
     white-space: nowrap;
-    animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000);
   }
 }
 
@@ -2768,11 +2918,20 @@ a.status-card {
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
-  width: 0;
-  height: 0;
+  width: 42px;
+  height: 42px;
   box-sizing: border-box;
+  background-color: transparent;
   border: 0 solid lighten($ui-base-color, 26%);
+  border-width: 6px;
   border-radius: 50%;
+}
+
+.no-reduce-motion .loading-indicator span {
+  animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000);
+}
+
+.no-reduce-motion .loading-indicator__figure {
   animation: loader-figure 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000);
 }
 
@@ -2897,6 +3056,26 @@ a.status-card {
   display: block;
   font-weight: 500;
   margin-bottom: 10px;
+
+  .column-settings__hashtag-select {
+    &__control {
+      @include search-input();
+    }
+
+    &__multi-value {
+      background: lighten($ui-base-color, 8%);
+    }
+
+    &__multi-value__label,
+    &__input {
+      color: $darker-text-color;
+    }
+
+    &__indicator-separator,
+    &__dropdown-indicator {
+      display: none;
+    }
+  }
 }
 
 .column-settings__row {
@@ -2948,8 +3127,7 @@ a.status-card {
   line-height: 24px;
 }
 
-.setting-toggle__label,
-.setting-meta__label {
+.setting-toggle__label {
   color: $darker-text-color;
   display: inline-block;
   margin-bottom: 14px;
@@ -2957,10 +3135,6 @@ a.status-card {
   vertical-align: middle;
 }
 
-.setting-meta__label {
-  float: right;
-}
-
 .empty-column-indicator,
 .error-column {
   color: $dark-text-color;
@@ -3259,7 +3433,14 @@ a.status-card {
   border-radius: 4px;
   margin-left: 40px;
   overflow: hidden;
-  transform-origin: 50% 0;
+
+  &.top {
+    transform-origin: 50% 100%;
+  }
+
+  &.bottom {
+    transform-origin: 50% 0;
+  }
 }
 
 .privacy-dropdown__option {
@@ -3331,6 +3512,10 @@ a.status-card {
     }
   }
 
+  &.top .privacy-dropdown__value {
+    border-radius: 0 0 4px 4px;
+  }
+
   .privacy-dropdown__dropdown {
     display: block;
     box-shadow: 2px 4px 6px rgba($base-shadow-color, 0.1);
@@ -3342,36 +3527,10 @@ a.status-card {
 }
 
 .search__input {
-  outline: 0;
-  box-sizing: border-box;
   display: block;
-  width: 100%;
-  border: none;
   padding: 10px;
   padding-right: 30px;
-  font-family: inherit;
-  background: $ui-base-color;
-  color: $darker-text-color;
-  font-size: 14px;
-  margin: 0;
-
-  &::-moz-focus-inner {
-    border: 0;
-  }
-
-  &::-moz-focus-inner,
-  &:focus,
-  &:active {
-    outline: 0 !important;
-  }
-
-  &:focus {
-    background: lighten($ui-base-color, 4%);
-  }
-
-  @media screen and (max-width: 600px) {
-    font-size: 16px;
-  }
+  @include search-input();
 }
 
 .search__icon {
@@ -3648,25 +3807,6 @@ a.status-card {
   flex-direction: column;
 }
 
-.onboarding-modal__pager {
-  height: 80vh;
-  width: 80vw;
-  max-width: 520px;
-  max-height: 470px;
-
-  .react-swipeable-view-container > div {
-    width: 100%;
-    height: 100%;
-    box-sizing: border-box;
-    display: none;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
-    display: flex;
-    user-select: text;
-  }
-}
-
 .error-modal__body {
   height: 80vh;
   width: 80vw;
@@ -3700,22 +3840,6 @@ a.status-card {
   text-align: center;
 }
 
-@media screen and (max-width: 550px) {
-  .onboarding-modal {
-    width: 100%;
-    height: 100%;
-    border-radius: 0;
-  }
-
-  .onboarding-modal__pager {
-    width: 100%;
-    height: auto;
-    max-width: none;
-    max-height: none;
-    flex: 1 1 auto;
-  }
-}
-
 .onboarding-modal__paginator,
 .error-modal__footer {
   flex: 0 0 auto;
@@ -3764,124 +3888,6 @@ a.status-card {
   justify-content: center;
 }
 
-.onboarding-modal__dots {
-  flex: 1 1 auto;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.onboarding-modal__dot {
-  width: 14px;
-  height: 14px;
-  border-radius: 14px;
-  background: darken($ui-secondary-color, 16%);
-  margin: 0 3px;
-  cursor: pointer;
-
-  &:hover {
-    background: darken($ui-secondary-color, 18%);
-  }
-
-  &.active {
-    cursor: default;
-    background: darken($ui-secondary-color, 24%);
-  }
-}
-
-.onboarding-modal__page__wrapper {
-  pointer-events: none;
-  padding: 25px;
-  padding-bottom: 0;
-
-  &.onboarding-modal__page__wrapper--active {
-    pointer-events: auto;
-  }
-}
-
-.onboarding-modal__page {
-  cursor: default;
-  line-height: 21px;
-
-  h1 {
-    font-size: 18px;
-    font-weight: 500;
-    color: $inverted-text-color;
-    margin-bottom: 20px;
-  }
-
-  a {
-    color: $highlight-text-color;
-
-    &:hover,
-    &:focus,
-    &:active {
-      color: lighten($highlight-text-color, 4%);
-    }
-  }
-
-  .navigation-bar a {
-    color: inherit;
-  }
-
-  p {
-    font-size: 16px;
-    color: $lighter-text-color;
-    margin-top: 10px;
-    margin-bottom: 10px;
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-
-    strong {
-      font-weight: 500;
-      background: $ui-base-color;
-      color: $secondary-text-color;
-      border-radius: 4px;
-      font-size: 14px;
-      padding: 3px 6px;
-
-      @each $lang in $cjk-langs {
-        &:lang(#{$lang}) {
-          font-weight: 700;
-        }
-      }
-    }
-  }
-}
-
-.onboarding-modal__page__wrapper-0 {
-  background: url('../images/elephant_ui_greeting.svg') no-repeat left bottom / auto 250px;
-  height: 100%;
-  padding: 0;
-}
-
-.onboarding-modal__page-one {
-  &__lead {
-    padding: 65px;
-    padding-top: 45px;
-    padding-bottom: 0;
-    margin-bottom: 10px;
-
-    h1 {
-      font-size: 26px;
-      line-height: 36px;
-      margin-bottom: 8px;
-    }
-
-    p {
-      margin-bottom: 0;
-    }
-  }
-
-  &__extra {
-    padding-right: 65px;
-    padding-left: 185px;
-    text-align: center;
-  }
-}
-
 .display-case {
   text-align: center;
   font-size: 15px;
@@ -3904,92 +3910,6 @@ a.status-card {
   }
 }
 
-.onboarding-modal__page-two,
-.onboarding-modal__page-three,
-.onboarding-modal__page-four,
-.onboarding-modal__page-five {
-  p {
-    text-align: left;
-  }
-
-  .figure {
-    background: darken($ui-base-color, 8%);
-    color: $secondary-text-color;
-    margin-bottom: 20px;
-    border-radius: 4px;
-    padding: 10px;
-    text-align: center;
-    font-size: 14px;
-    box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.3);
-
-    .onboarding-modal__image {
-      border-radius: 4px;
-      margin-bottom: 10px;
-    }
-
-    &.non-interactive {
-      pointer-events: none;
-      text-align: left;
-    }
-  }
-}
-
-.onboarding-modal__page-four__columns {
-  .row {
-    display: flex;
-    margin-bottom: 20px;
-
-    & > div {
-      flex: 1 1 0;
-      margin: 0 10px;
-
-      &:first-child {
-        margin-left: 0;
-      }
-
-      &:last-child {
-        margin-right: 0;
-      }
-
-      p {
-        text-align: center;
-      }
-    }
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-  }
-
-  .column-header {
-    color: $primary-text-color;
-  }
-}
-
-@media screen and (max-width: 320px) and (max-height: 600px) {
-  .onboarding-modal__page p {
-    font-size: 14px;
-    line-height: 20px;
-  }
-
-  .onboarding-modal__page-two .figure,
-  .onboarding-modal__page-three .figure,
-  .onboarding-modal__page-four .figure,
-  .onboarding-modal__page-five .figure {
-    font-size: 12px;
-    margin-bottom: 10px;
-  }
-
-  .onboarding-modal__page-four__columns .row {
-    margin-bottom: 10px;
-  }
-
-  .onboarding-modal__page-four__columns .column-header {
-    padding: 5px;
-    font-size: 12px;
-  }
-}
-
 .onboard-sliders {
   display: inline-block;
   max-width: 30px;
@@ -4135,6 +4055,11 @@ a.status-card {
     color: $highlight-text-color;
   }
 
+  .status__content,
+  .status__content p {
+    color: $inverted-text-color;
+  }
+
   @media screen and (max-width: 480px) {
     max-height: 10vh;
   }
@@ -4519,6 +4444,19 @@ a.status-card {
   z-index: 5;
 }
 
+.detailed,
+.fullscreen {
+  .video-player__volume__current,
+  .video-player__volume::before {
+    bottom: 27px;
+  }
+
+  .video-player__volume__handle {
+    bottom: 23px;
+  }
+
+}
+
 .video-player {
   overflow: hidden;
   position: relative;
@@ -4667,7 +4605,7 @@ a.status-card {
 
   &__time-current {
     color: $white;
-    margin-left: 10px;
+    margin-left: 60px;
   }
 
   &__time-sep {
@@ -4680,6 +4618,48 @@ a.status-card {
     color: $white;
   }
 
+  &__volume {
+    cursor: pointer;
+    height: 24px;
+    display: inline;
+
+    &::before {
+      content: "";
+      width: 50px;
+      background: rgba($white, 0.35);
+      border-radius: 4px;
+      display: block;
+      position: absolute;
+      height: 4px;
+      left: 70px;
+      bottom: 20px;
+    }
+
+    &__current {
+      display: block;
+      position: absolute;
+      height: 4px;
+      border-radius: 4px;
+      left: 70px;
+      bottom: 20px;
+      background: lighten($ui-highlight-color, 8%);
+    }
+
+    &__handle {
+      position: absolute;
+      z-index: 3;
+      border-radius: 50%;
+      width: 12px;
+      height: 12px;
+      bottom: 16px;
+      left: 70px;
+      transition: opacity .1s ease;
+      background: lighten($ui-highlight-color, 8%);
+      box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
+      pointer-events: none;
+    }
+  }
+
   &__seek {
     cursor: pointer;
     height: 24px;
@@ -4830,12 +4810,21 @@ a.status-card {
   }
 }
 
+.notification__filter-bar,
 .account__section-headline {
   background: darken($ui-base-color, 4%);
   border-bottom: 1px solid lighten($ui-base-color, 8%);
   cursor: default;
   display: flex;
+  flex-shrink: 0;
 
+  button {
+    background: darken($ui-base-color, 4%);
+    border: 0;
+    margin: 0;
+  }
+
+  button,
   a {
     display: block;
     flex: 1 1 auto;
@@ -5046,7 +5035,7 @@ noscript {
       width: 100%;
       border: none;
       padding: 10px;
-      font-family: 'mastodon-font-monospace', monospace;
+      font-family: $font-monospace, monospace;
       background: $ui-base-color;
       color: $primary-text-color;
       font-size: 14px;
@@ -5209,6 +5198,47 @@ noscript {
   }
 }
 
+.list-adder {
+  background: $ui-base-color;
+  flex-direction: column;
+  border-radius: 8px;
+  box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
+  width: 380px;
+  overflow: hidden;
+
+  @media screen and (max-width: 420px) {
+    width: 90%;
+  }
+
+  &__account {
+    background: lighten($ui-base-color, 13%);
+  }
+
+  &__lists {
+    background: lighten($ui-base-color, 13%);
+    height: 50vh;
+    border-radius: 0 0 8px 8px;
+    overflow-y: auto;
+  }
+
+  .list {
+    padding: 10px;
+    border-bottom: 1px solid lighten($ui-base-color, 8%);
+  }
+
+  .list__wrapper {
+    display: flex;
+  }
+
+  .list__display-name {
+    flex: 1 1 auto;
+    overflow: hidden;
+    text-decoration: none;
+    font-size: 16px;
+    padding: 10px;
+  }
+}
+
 .focal-point-modal {
   max-width: 80vw;
   max-height: 80vh;
@@ -5287,16 +5317,18 @@ noscript {
   overflow: hidden;
   margin: 20px -10px -20px;
   border-bottom: 0;
+  border-top: 0;
 
   dl {
-    border-top: 1px solid lighten($ui-base-color, 8%);
+    border-top: 1px solid lighten($ui-base-color, 4%);
+    border-bottom: 0;
     display: flex;
   }
 
   dt,
   dd {
     box-sizing: border-box;
-    padding: 14px 20px;
+    padding: 14px 5px;
     text-align: center;
     max-height: 48px;
     overflow: hidden;
@@ -5316,6 +5348,11 @@ noscript {
     flex: 1 1 auto;
     color: $primary-text-color;
     background: $ui-base-color;
+
+    &.verified {
+      border: 1px solid rgba($valid-value-color, 0.5);
+      background: rgba($valid-value-color, 0.25);
+    }
   }
 }
 
diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss
index ac648c8680eb6152759ef103de88ea87085bb94d..a98fa52c47bb2b45b6f1c6fa8c9de4cf9cc5f8d3 100644
--- a/app/javascript/styles/mastodon/containers.scss
+++ b/app/javascript/styles/mastodon/containers.scss
@@ -37,7 +37,7 @@
       outline: 0;
       padding: 12px 16px;
       line-height: 32px;
-      font-family: 'mastodon-font-display', sans-serif;
+      font-family: $font-display, sans-serif;
       font-weight: 500;
       font-size: 14px;
     }
@@ -60,10 +60,6 @@
   }
 }
 
-.media-standalone__body {
-  overflow: hidden;
-}
-
 .account-header {
   width: 400px;
   margin: 0 auto;
@@ -118,3 +114,701 @@
     margin-left: 8px;
   }
 }
+
+.grid-3 {
+  display: grid;
+  grid-gap: 10px;
+  grid-template-columns: 3fr 1fr;
+  grid-auto-columns: 25%;
+  grid-auto-rows: max-content;
+
+  .column-0 {
+    grid-column: 1/3;
+    grid-row: 1;
+  }
+
+  .column-1 {
+    grid-column: 1;
+    grid-row: 2;
+  }
+
+  .column-2 {
+    grid-column: 2;
+    grid-row: 2;
+  }
+
+  .column-3 {
+    grid-column: 1/3;
+    grid-row: 3;
+  }
+
+  .landing-page__call-to-action {
+    min-height: 100%;
+  }
+
+  @media screen and (max-width: 738px) {
+    grid-template-columns: minmax(0, 50%) minmax(0, 50%);
+
+    .landing-page__call-to-action {
+      padding: 20px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+
+    .row__information-board {
+      width: 100%;
+      justify-content: center;
+      align-items: center;
+    }
+
+    .row__mascot {
+      display: none;
+    }
+  }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    grid-gap: 0;
+    grid-template-columns: minmax(0, 100%);
+
+    .column-0 {
+      grid-column: 1;
+    }
+
+    .column-1 {
+      grid-column: 1;
+      grid-row: 3;
+    }
+
+    .column-2 {
+      grid-column: 1;
+      grid-row: 2;
+    }
+
+    .column-3 {
+      grid-column: 1;
+      grid-row: 4;
+    }
+  }
+}
+
+.public-layout {
+  @media screen and (max-width: $no-gap-breakpoint) {
+    padding-top: 48px;
+  }
+
+  .container {
+    max-width: 960px;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      padding: 0;
+    }
+  }
+
+  .header {
+    background: lighten($ui-base-color, 8%);
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    border-radius: 4px;
+    height: 48px;
+    margin: 10px 0;
+    display: flex;
+    align-items: stretch;
+    justify-content: center;
+    flex-wrap: nowrap;
+    overflow: hidden;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      position: fixed;
+      width: 100%;
+      top: 0;
+      left: 0;
+      margin: 0;
+      border-radius: 0;
+      box-shadow: none;
+      z-index: 110;
+    }
+
+    & > div {
+      flex: 1 1 33.3%;
+      min-height: 1px;
+    }
+
+    .nav-left {
+      display: flex;
+      align-items: stretch;
+      justify-content: flex-start;
+      flex-wrap: nowrap;
+    }
+
+    .nav-center {
+      display: flex;
+      align-items: stretch;
+      justify-content: center;
+      flex-wrap: nowrap;
+    }
+
+    .nav-right {
+      display: flex;
+      align-items: stretch;
+      justify-content: flex-end;
+      flex-wrap: nowrap;
+    }
+
+    .brand {
+      display: block;
+      padding: 15px;
+
+      img {
+        display: block;
+        height: 18px;
+        width: auto;
+        position: relative;
+        bottom: -2px;
+
+        @media screen and (max-width: $no-gap-breakpoint) {
+          height: 20px;
+        }
+      }
+
+      &:hover,
+      &:focus,
+      &:active {
+        background: lighten($ui-base-color, 12%);
+      }
+    }
+
+    .nav-link {
+      display: flex;
+      align-items: center;
+      padding: 0 1rem;
+      font-size: 12px;
+      font-weight: 500;
+      text-decoration: none;
+      color: $darker-text-color;
+      white-space: nowrap;
+      text-align: center;
+
+      &:hover,
+      &:focus,
+      &:active {
+        text-decoration: underline;
+        color: $primary-text-color;
+      }
+
+      @media screen and (max-width: 550px) {
+        &.optional {
+          display: none;
+        }
+      }
+    }
+
+    .nav-button {
+      background: lighten($ui-base-color, 16%);
+      margin: 8px;
+      margin-left: 0;
+      border-radius: 4px;
+
+      &:hover,
+      &:focus,
+      &:active {
+        text-decoration: none;
+        background: lighten($ui-base-color, 20%);
+      }
+    }
+  }
+
+  $no-columns-breakpoint: 600px;
+
+  .grid {
+    display: grid;
+    grid-gap: 10px;
+    grid-template-columns: minmax(300px, 3fr) minmax(298px, 1fr);
+    grid-auto-columns: 25%;
+    grid-auto-rows: max-content;
+
+    .column-0 {
+      grid-row: 1;
+      grid-column: 1;
+    }
+
+    .column-1 {
+      grid-row: 1;
+      grid-column: 2;
+    }
+
+    @media screen and (max-width: $no-columns-breakpoint) {
+      grid-template-columns: 100%;
+      grid-gap: 0;
+
+      .column-1 {
+        display: none;
+      }
+    }
+  }
+
+  .public-account-header {
+    overflow: hidden;
+    margin-bottom: 10px;
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+
+    &.inactive {
+      opacity: 0.5;
+
+      .public-account-header__image,
+      .avatar {
+        filter: grayscale(100%);
+      }
+
+      .logo-button {
+        background-color: $secondary-text-color;
+
+        svg path:last-child {
+          fill: $secondary-text-color;
+        }
+      }
+    }
+
+    &__image {
+      border-radius: 4px 4px 0 0;
+      overflow: hidden;
+      height: 300px;
+      position: relative;
+      background: darken($ui-base-color, 12%);
+
+      &::after {
+        content: "";
+        display: block;
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        box-shadow: inset 0 -1px 1px 1px rgba($base-shadow-color, 0.15);
+        top: 0;
+        left: 0;
+      }
+
+      img {
+        object-fit: cover;
+        display: block;
+        width: 100%;
+        height: 100%;
+        margin: 0;
+        border-radius: 4px 4px 0 0;
+      }
+
+      @media screen and (max-width: 600px) {
+        height: 200px;
+      }
+    }
+
+    &--no-bar {
+      margin-bottom: 0;
+
+      .public-account-header__image,
+      .public-account-header__image img {
+        border-radius: 4px;
+
+        @media screen and (max-width: $no-gap-breakpoint) {
+          border-radius: 0;
+        }
+      }
+    }
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      margin-bottom: 0;
+      box-shadow: none;
+
+      &__image::after {
+        display: none;
+      }
+
+      &__image,
+      &__image img {
+        border-radius: 0;
+      }
+    }
+
+    &__bar {
+      position: relative;
+      margin-top: -80px;
+      display: flex;
+      justify-content: flex-start;
+
+      &::before {
+        content: "";
+        display: block;
+        background: lighten($ui-base-color, 4%);
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        height: 60px;
+        border-radius: 0 0 4px 4px;
+        z-index: -1;
+      }
+
+      .avatar {
+        display: block;
+        width: 120px;
+        height: 120px;
+        padding-left: 20px - 4px;
+        flex: 0 0 auto;
+
+        img {
+          display: block;
+          width: 100%;
+          height: 100%;
+          margin: 0;
+          border-radius: 50%;
+          border: 4px solid lighten($ui-base-color, 4%);
+          background: darken($ui-base-color, 8%);
+        }
+      }
+
+      @media screen and (max-width: 600px) {
+        margin-top: 0;
+        background: lighten($ui-base-color, 4%);
+        border-radius: 0 0 4px 4px;
+        padding: 5px;
+
+        &::before {
+          display: none;
+        }
+
+        .avatar {
+          width: 48px;
+          height: 48px;
+          padding: 7px 0;
+          padding-left: 10px;
+
+          img {
+            border: 0;
+            border-radius: 4px;
+          }
+
+          @media screen and (max-width: 360px) {
+            display: none;
+          }
+        }
+      }
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        border-radius: 0;
+      }
+
+      @media screen and (max-width: $no-columns-breakpoint) {
+        flex-wrap: wrap;
+      }
+    }
+
+    &__tabs {
+      flex: 1 1 auto;
+      margin-left: 20px;
+
+      &__name {
+        padding-top: 20px;
+        padding-bottom: 8px;
+
+        h1 {
+          font-size: 20px;
+          line-height: 18px * 1.5;
+          color: $primary-text-color;
+          font-weight: 500;
+          overflow: hidden;
+          white-space: nowrap;
+          text-overflow: ellipsis;
+          text-shadow: 1px 1px 1px $base-shadow-color;
+
+          small {
+            display: block;
+            font-size: 14px;
+            color: $primary-text-color;
+            font-weight: 400;
+            overflow: hidden;
+            text-overflow: ellipsis;
+          }
+        }
+      }
+
+      @media screen and (max-width: 600px) {
+        margin-left: 15px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        &__name {
+          padding-top: 0;
+          padding-bottom: 0;
+
+          h1 {
+            font-size: 16px;
+            line-height: 24px;
+            text-shadow: none;
+
+            small {
+              color: $darker-text-color;
+            }
+          }
+        }
+      }
+
+      &__tabs {
+        display: flex;
+        justify-content: flex-start;
+        align-items: stretch;
+        height: 58px;
+
+        .details-counters {
+          display: flex;
+          flex-direction: row;
+          min-width: 300px;
+        }
+
+        @media screen and (max-width: $no-columns-breakpoint) {
+          .details-counters {
+            display: none;
+          }
+        }
+
+        .counter {
+          width: 33.3%;
+          box-sizing: border-box;
+          flex: 0 0 auto;
+          color: $darker-text-color;
+          padding: 10px;
+          border-right: 1px solid lighten($ui-base-color, 4%);
+          cursor: default;
+          text-align: center;
+          position: relative;
+
+          a {
+            display: block;
+          }
+
+          &:last-child {
+            border-right: 0;
+          }
+
+          &::after {
+            display: block;
+            content: "";
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            width: 100%;
+            border-bottom: 4px solid $ui-primary-color;
+            opacity: 0.5;
+            transition: all 400ms ease;
+          }
+
+          &.active {
+            &::after {
+              border-bottom: 4px solid $highlight-text-color;
+              opacity: 1;
+            }
+
+            &.inactive::after {
+              border-bottom-color: $secondary-text-color;
+            }
+          }
+
+          &:hover {
+            &::after {
+              opacity: 1;
+              transition-duration: 100ms;
+            }
+          }
+
+          a {
+            text-decoration: none;
+            color: inherit;
+          }
+
+          .counter-label {
+            font-size: 12px;
+            display: block;
+          }
+
+          .counter-number {
+            font-weight: 500;
+            font-size: 18px;
+            margin-bottom: 5px;
+            color: $primary-text-color;
+            font-family: $font-display, sans-serif;
+          }
+        }
+
+        .spacer {
+          flex: 1 1 auto;
+          height: 1px;
+        }
+
+        &__buttons {
+          padding: 7px 8px;
+        }
+      }
+    }
+
+    &__extra {
+      display: none;
+      margin-top: 4px;
+
+      .public-account-bio {
+        border-radius: 0;
+        box-shadow: none;
+        background: transparent;
+        margin: 0 -5px;
+
+        .account__header__fields {
+          border-top: 1px solid lighten($ui-base-color, 12%);
+        }
+
+        .roles {
+          display: none;
+        }
+      }
+
+      &__links {
+        margin-top: -15px;
+        font-size: 14px;
+        color: $darker-text-color;
+
+        a {
+          display: inline-block;
+          color: $darker-text-color;
+          text-decoration: none;
+          padding: 15px;
+
+          strong {
+            font-weight: 700;
+            color: $primary-text-color;
+          }
+        }
+      }
+
+      @media screen and (max-width: $no-columns-breakpoint) {
+        display: block;
+        flex: 100%;
+      }
+    }
+  }
+
+  .account__section-headline {
+    border-radius: 4px 4px 0 0;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-radius: 0;
+    }
+  }
+
+  .detailed-status__meta {
+    margin-top: 25px;
+  }
+
+  .public-account-bio {
+    background: lighten($ui-base-color, 8%);
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    border-radius: 4px;
+    overflow: hidden;
+    margin-bottom: 10px;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      box-shadow: none;
+      margin-bottom: 0;
+      border-radius: 0;
+    }
+
+    .account__header__fields {
+      margin: 0;
+      border-top: 0;
+
+      a {
+        color: lighten($ui-highlight-color, 8%);
+      }
+
+      dl:first-child .verified {
+        border-radius: 0 4px 0 0;
+      }
+
+      .verified a {
+        color: $valid-value-color;
+      }
+    }
+
+    .account__header__content {
+      padding: 20px;
+      padding-bottom: 0;
+      color: $primary-text-color;
+    }
+
+    &__extra,
+    .roles {
+      padding: 20px;
+      font-size: 14px;
+      color: $darker-text-color;
+    }
+
+    .roles {
+      padding-bottom: 0;
+    }
+  }
+
+  .static-icon-button {
+    color: $action-button-color;
+    font-size: 18px;
+
+    & > span {
+      font-size: 14px;
+      font-weight: 500;
+    }
+  }
+
+  .card-grid {
+    display: flex;
+    flex-wrap: wrap;
+    min-width: 100%;
+    margin: 0 -5px;
+
+    & > div {
+      box-sizing: border-box;
+      flex: 1 0 auto;
+      width: 300px;
+      padding: 0 5px;
+      margin-bottom: 10px;
+      max-width: 33.333%;
+
+      @media screen and (max-width: 900px) {
+        max-width: 50%;
+      }
+
+      @media screen and (max-width: 600px) {
+        max-width: 100%;
+      }
+    }
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      margin: 0;
+      border-top: 1px solid lighten($ui-base-color, 8%);
+
+      & > div {
+        width: 100%;
+        padding: 0;
+        margin-bottom: 0;
+        border-bottom: 1px solid lighten($ui-base-color, 8%);
+
+        &:last-child {
+          border-bottom: 0;
+        }
+
+        .card__bar {
+          background: $ui-base-color;
+
+          &:hover,
+          &:active,
+          &:focus {
+            background: lighten($ui-base-color, 4%);
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/app/javascript/styles/mastodon/dashboard.scss b/app/javascript/styles/mastodon/dashboard.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e4564f062cd7bbb97028507eab9083c49c012cbc
--- /dev/null
+++ b/app/javascript/styles/mastodon/dashboard.scss
@@ -0,0 +1,76 @@
+.dashboard__counters {
+  display: flex;
+  flex-wrap: wrap;
+  margin: 0 -5px;
+  margin-bottom: 20px;
+
+  & > div {
+    box-sizing: border-box;
+    flex: 0 0 33.333%;
+    padding: 0 5px;
+    margin-bottom: 10px;
+
+    & > div,
+    & > a {
+      padding: 20px;
+      background: lighten($ui-base-color, 4%);
+      border-radius: 4px;
+    }
+
+    & > a {
+      text-decoration: none;
+      color: inherit;
+      display: block;
+
+      &:hover,
+      &:focus,
+      &:active {
+        background: lighten($ui-base-color, 8%);
+      }
+    }
+  }
+
+  &__num,
+  &__text {
+    text-align: center;
+    font-weight: 500;
+    font-size: 24px;
+    line-height: 21px;
+    color: $primary-text-color;
+    font-family: $font-display, sans-serif;
+    margin-bottom: 20px;
+    line-height: 30px;
+  }
+
+  &__text {
+    font-size: 18px;
+  }
+
+  &__label {
+    font-size: 14px;
+    color: $darker-text-color;
+    text-align: center;
+    font-weight: 500;
+  }
+}
+
+.dashboard__widgets {
+  display: flex;
+  flex-wrap: wrap;
+  margin: 0 -5px;
+
+  & > div {
+    flex: 0 0 33.333%;
+    margin-bottom: 20px;
+
+    & > div {
+      padding: 0 5px;
+    }
+  }
+
+  a:not(.name-tag) {
+    color: $ui-secondary-color;
+    font-weight: 500;
+    text-decoration: none;
+  }
+}
diff --git a/app/javascript/styles/mastodon/footer.scss b/app/javascript/styles/mastodon/footer.scss
index 81eb1ce2d31e2003c36e261dddb66c24a9cce753..4d75477e09b8786de6899deaa556d4e869a58938 100644
--- a/app/javascript/styles/mastodon/footer.scss
+++ b/app/javascript/styles/mastodon/footer.scss
@@ -1,39 +1,140 @@
-.footer {
-  text-align: center;
-  margin-top: 30px;
-  padding-bottom: 60px;
-  font-size: 12px;
-  color: $darker-text-color;
-
-  .footer__domain {
-    font-weight: 500;
-
-    a {
-      color: inherit;
-      text-decoration: none;
+.public-layout {
+  .footer {
+    text-align: left;
+    padding-top: 20px;
+    padding-bottom: 60px;
+    font-size: 12px;
+    color: lighten($ui-base-color, 34%);
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      padding-left: 20px;
+      padding-right: 20px;
     }
-  }
 
-  .powered-by,
-  .single-user-login {
-    font-weight: 400;
+    .grid {
+      display: grid;
+      grid-gap: 10px;
+      grid-template-columns: 1fr 1fr 2fr 1fr 1fr;
+
+      .column-0 {
+        grid-column: 1;
+        grid-row: 1;
+        min-width: 0;
+      }
+
+      .column-1 {
+        grid-column: 2;
+        grid-row: 1;
+        min-width: 0;
+      }
+
+      .column-2 {
+        grid-column: 3;
+        grid-row: 1;
+        min-width: 0;
+        text-align: center;
+
+        h4 a {
+          color: lighten($ui-base-color, 34%);
+        }
+      }
+
+      .column-3 {
+        grid-column: 4;
+        grid-row: 1;
+        min-width: 0;
+      }
+
+      .column-4 {
+        grid-column: 5;
+        grid-row: 1;
+        min-width: 0;
+      }
+
+      @media screen and (max-width: 690px) {
+        grid-template-columns: 1fr 2fr 1fr;
+
+        .column-0,
+        .column-1 {
+          grid-column: 1;
+        }
+
+        .column-1 {
+          grid-row: 2;
+        }
+
+        .column-2 {
+          grid-column: 2;
+        }
 
-    a {
-      color: inherit;
-      text-decoration: underline;
-      font-weight: 500;
+        .column-3,
+        .column-4 {
+          grid-column: 3;
+        }
 
-      &:hover {
+        .column-4 {
+          grid-row: 2;
+        }
+      }
+
+      @media screen and (max-width: 600px) {
+        .column-1 {
+          display: block;
+        }
+      }
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        .column-0,
+        .column-1,
+        .column-3,
+        .column-4 {
+          display: none;
+        }
+      }
+    }
+
+    h4 {
+      text-transform: uppercase;
+      font-weight: 700;
+      margin-bottom: 8px;
+      color: $darker-text-color;
+
+      a {
+        color: inherit;
         text-decoration: none;
       }
     }
 
-    img {
-      margin: 0 4px;
-      position: relative;
-      bottom: -1px;
-      height: 18px;
-      vertical-align: top;
+    ul a {
+      text-decoration: none;
+      color: lighten($ui-base-color, 34%);
+
+      &:hover,
+      &:active,
+      &:focus {
+        text-decoration: underline;
+      }
+    }
+
+    .brand {
+      svg {
+        display: block;
+        height: 36px;
+        width: auto;
+        margin: 0 auto;
+
+        path {
+          fill: lighten($ui-base-color, 34%);
+        }
+      }
+
+      &:hover,
+      &:focus,
+      &:active {
+        svg path {
+          fill: lighten($ui-base-color, 38%);
+        }
+      }
     }
   }
 }
diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss
index 375c7b64bb443fe581a3cda27ff3a17f56e7cb70..bab982706fd5c53bd9469bf2e9f70663492e682c 100644
--- a/app/javascript/styles/mastodon/forms.scss
+++ b/app/javascript/styles/mastodon/forms.scss
@@ -1,5 +1,7 @@
+$no-columns-breakpoint: 600px;
+
 code {
-  font-family: 'mastodon-font-monospace', monospace;
+  font-family: $font-monospace, monospace;
   font-weight: 400;
 }
 
@@ -13,6 +15,60 @@ code {
   .input {
     margin-bottom: 15px;
     overflow: hidden;
+
+    &.hidden {
+      margin: 0;
+    }
+
+    &.radio_buttons {
+      .radio {
+        margin-bottom: 15px;
+
+        &:last-child {
+          margin-bottom: 0;
+        }
+      }
+
+      .radio > label {
+        position: relative;
+        padding-left: 28px;
+
+        input {
+          position: absolute;
+          top: -2px;
+          left: 0;
+        }
+      }
+    }
+
+    &.boolean {
+      position: relative;
+      margin-bottom: 0;
+
+      .label_input > label {
+        font-family: inherit;
+        font-size: 14px;
+        padding-top: 5px;
+        color: $primary-text-color;
+        display: block;
+        width: auto;
+      }
+
+      .label_input,
+      .hint {
+        padding-left: 28px;
+      }
+
+      .label_input__wrapper {
+        position: static;
+      }
+
+      label.checkbox {
+        position: absolute;
+        top: 2px;
+        left: 0;
+      }
+    }
   }
 
   .row {
@@ -27,9 +83,22 @@ code {
     }
   }
 
+  .hint {
+    color: $darker-text-color;
+
+    a {
+      color: $highlight-text-color;
+    }
+
+    code {
+      border-radius: 3px;
+      padding: 0.2em 0.4em;
+      background: darken($ui-base-color, 12%);
+    }
+  }
+
   span.hint {
     display: block;
-    color: $darker-text-color;
     font-size: 12px;
     margin-top: 4px;
   }
@@ -44,11 +113,6 @@ code {
       line-height: 18px;
       margin-top: 15px;
       margin-bottom: 0;
-      color: $darker-text-color;
-
-      a {
-        color: $highlight-text-color;
-      }
     }
   }
 
@@ -66,87 +130,60 @@ code {
     }
   }
 
-  .label_input {
-    display: flex;
+  .input.with_floating_label {
+    .label_input {
+      display: flex;
 
-    label {
-      flex: 0 0 auto;
+      & > label {
+        font-family: inherit;
+        font-size: 14px;
+        color: $primary-text-color;
+        font-weight: 500;
+        min-width: 150px;
+        flex: 0 0 auto;
+      }
+
+      input,
+      select {
+        flex: 1 1 auto;
+      }
     }
 
-    input {
-      flex: 1 1 auto;
+    &.select .hint {
+      margin-top: 6px;
+      margin-left: 150px;
     }
   }
 
   .input.with_label {
-    padding: 15px 0;
-    margin-bottom: 0;
-
-    .label_input {
-      flex-wrap: wrap;
-      align-items: flex-start;
-    }
-
-    &.file .label_input {
-      flex-wrap: nowrap;
-    }
-
-    &.select .label_input {
-      align-items: initial;
-    }
-
     .label_input > label {
       font-family: inherit;
-      font-size: 16px;
+      font-size: 14px;
       color: $primary-text-color;
       display: block;
-      padding-top: 5px;
-      margin-bottom: 5px;
-      flex: 1;
-      min-width: 150px;
+      margin-bottom: 8px;
       word-wrap: break-word;
+      font-weight: 500;
+    }
 
-      &.select {
-        flex: 0;
-      }
-
-      & ~ * {
-        margin-left: 10px;
-      }
+    .hint {
+      margin-top: 6px;
     }
 
     ul {
       flex: 390px;
     }
-
-    &.boolean {
-      padding: initial;
-      margin-bottom: initial;
-
-      .label_input > label {
-        font-family: inherit;
-        font-size: 14px;
-        color: $primary-text-color;
-        display: block;
-        width: auto;
-      }
-
-      label.checkbox {
-        position: relative;
-        padding-left: 25px;
-        flex: 1 1 auto;
-      }
-    }
   }
 
   .input.with_block_label {
-    padding-top: 15px;
+    max-width: none;
 
     & > label {
       font-family: inherit;
       font-size: 16px;
       color: $primary-text-color;
       display: block;
+      font-weight: 500;
       padding-top: 5px;
     }
 
@@ -154,62 +191,82 @@ code {
       margin-bottom: 15px;
     }
 
-    li {
-      float: left;
-      width: 50%;
+    ul {
+      columns: 2;
     }
   }
 
+  .required abbr {
+    text-decoration: none;
+    color: lighten($error-value-color, 12%);
+  }
+
   .fields-group {
     margin-bottom: 25px;
-  }
 
-  .input.radio_buttons .radio label {
-    margin-bottom: 5px;
-    font-family: inherit;
-    font-size: 14px;
-    color: $primary-text-color;
-    display: block;
-    width: auto;
+    .input:last-child {
+      margin-bottom: 0;
+    }
   }
 
-  .input.boolean {
-    margin-bottom: 5px;
+  .fields-row {
+    display: flex;
+    margin: 0 -10px;
+    padding-top: 5px;
+    margin-bottom: 25px;
 
-    label {
-      font-family: inherit;
-      font-size: 14px;
-      color: $primary-text-color;
-      display: block;
-      width: auto;
+    .input {
+      max-width: none;
     }
 
-    label.checkbox {
-      position: relative;
-      padding-left: 25px;
+    &__column {
+      box-sizing: border-box;
+      padding: 0 10px;
       flex: 1 1 auto;
+      min-height: 1px;
+
+      &-6 {
+        max-width: 50%;
+      }
     }
 
-    input[type=checkbox] {
-      position: absolute;
-      left: 0;
-      top: 5px;
-      margin: 0;
+    .fields-group:last-child,
+    .fields-row__column.fields-group {
+      margin-bottom: 0;
     }
 
-    .hint {
-      padding-left: 25px;
-      margin-left: 0;
+    @media screen and (max-width: $no-columns-breakpoint) {
+      display: block;
+      margin-bottom: 0;
+
+      &__column {
+        max-width: none;
+      }
+
+      .fields-group:last-child,
+      .fields-row__column.fields-group,
+      .fields-row__column {
+        margin-bottom: 25px;
+      }
     }
   }
 
+  .input.radio_buttons .radio label {
+    margin-bottom: 5px;
+    font-family: inherit;
+    font-size: 14px;
+    color: $primary-text-color;
+    display: block;
+    width: auto;
+  }
+
   .check_boxes {
     .checkbox {
       label {
         font-family: inherit;
         font-size: 14px;
         color: $primary-text-color;
-        display: block;
+        display: inline-block;
         width: auto;
         position: relative;
         padding-top: 5px;
@@ -231,12 +288,7 @@ code {
   input[type=email],
   input[type=password],
   textarea {
-    background: transparent;
     box-sizing: border-box;
-    border: 0;
-    border-bottom: 2px solid $ui-primary-color;
-    border-radius: 2px 2px 0 0;
-    padding: 7px 4px;
     font-size: 16px;
     color: $primary-text-color;
     display: block;
@@ -244,23 +296,31 @@ code {
     outline: 0;
     font-family: inherit;
     resize: vertical;
+    background: darken($ui-base-color, 10%);
+    border: 1px solid darken($ui-base-color, 14%);
+    border-radius: 4px;
+    padding: 10px;
 
     &:invalid {
       box-shadow: none;
     }
 
     &:focus:invalid {
-      border-bottom-color: lighten($error-red, 12%);
+      border-color: lighten($error-red, 12%);
     }
 
     &:required:valid {
-      border-bottom-color: $valid-value-color;
+      border-color: $valid-value-color;
+    }
+
+    &:hover {
+      border-color: darken($ui-base-color, 20%);
     }
 
     &:active,
     &:focus {
-      border-bottom-color: $highlight-text-color;
-      background: rgba($base-overlay-background, 0.1);
+      border-color: $highlight-text-color;
+      background: darken($ui-base-color, 8%);
     }
   }
 
@@ -270,9 +330,12 @@ code {
     }
 
     input[type=text],
+    input[type=number],
     input[type=email],
-    input[type=password] {
-      border-bottom-color: $valid-value-color;
+    input[type=password],
+    textarea,
+    select {
+      border-color: lighten($error-red, 12%);
     }
 
     .error {
@@ -344,22 +407,33 @@ code {
   }
 
   select {
+    appearance: none;
+    box-sizing: border-box;
     font-size: 16px;
-    max-height: 29px;
+    color: $primary-text-color;
+    display: block;
+    width: 100%;
+    outline: 0;
+    font-family: inherit;
+    resize: vertical;
+    background: darken($ui-base-color, 10%) 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, 12%))}'/></svg>") no-repeat right 8px center / auto 16px;
+    border: 1px solid darken($ui-base-color, 14%);
+    border-radius: 4px;
+    padding-left: 10px;
+    padding-right: 30px;
+    height: 41px;
   }
 
-  .input-with-append {
-    position: relative;
-
-    .input input {
-      padding-right: 142px;
+  .label_input {
+    &__wrapper {
+      position: relative;
     }
 
-    .append {
+    &__append {
       position: absolute;
-      right: 0;
-      top: 0;
-      padding: 7px 4px;
+      right: 3px;
+      top: 1px;
+      padding: 10px;
       padding-bottom: 9px;
       font-size: 16px;
       color: $dark-text-color;
@@ -378,7 +452,7 @@ code {
         right: 0;
         bottom: 1px;
         width: 5px;
-        background-image: linear-gradient(to right, rgba($ui-base-color, 0), $ui-base-color);
+        background-image: linear-gradient(to right, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%));
       }
     }
   }
@@ -390,9 +464,20 @@ code {
   border-radius: 4px;
   padding: 15px 10px;
   margin-bottom: 30px;
-  box-shadow: 0 0 5px rgba($base-shadow-color, 0.2);
   text-align: center;
 
+  &.notice {
+    border: 1px solid rgba($valid-value-color, 0.5);
+    background: rgba($valid-value-color, 0.25);
+    color: $valid-value-color;
+  }
+
+  &.alert {
+    border: 1px solid rgba($error-value-color, 0.5);
+    background: rgba($error-value-color, 0.25);
+    color: $error-value-color;
+  }
+
   p {
     margin-bottom: 15px;
   }
@@ -404,7 +489,7 @@ code {
     width: 100%;
     border: none;
     padding: 10px;
-    font-family: 'mastodon-font-monospace', monospace;
+    font-family: $font-monospace, monospace;
     background: $ui-base-color;
     color: $primary-text-color;
     font-size: 14px;
@@ -454,15 +539,39 @@ code {
   }
 }
 
+.quick-nav {
+  list-style: none;
+  margin-bottom: 25px;
+  font-size: 14px;
+
+  li {
+    display: inline-block;
+    margin-right: 10px;
+  }
+
+  a {
+    color: $highlight-text-color;
+    text-transform: uppercase;
+    text-decoration: none;
+    font-weight: 700;
+
+    &:hover,
+    &:focus,
+    &:active {
+      color: lighten($highlight-text-color, 8%);
+    }
+  }
+}
+
 .oauth-prompt,
 .follow-prompt {
   margin-bottom: 30px;
-  text-align: center;
   color: $darker-text-color;
 
   h2 {
     font-size: 16px;
     margin-bottom: 30px;
+    text-align: center;
   }
 
   strong {
@@ -616,3 +725,60 @@ code {
 .scope-danger {
   color: $warning-red;
 }
+
+.form_admin_settings_site_short_description,
+.form_admin_settings_site_description,
+.form_admin_settings_site_extended_description,
+.form_admin_settings_site_terms,
+.form_admin_settings_custom_css,
+.form_admin_settings_closed_registrations_message {
+  textarea {
+    font-family: $font-monospace, monospace;
+  }
+}
+
+.input-copy {
+  background: darken($ui-base-color, 10%);
+  border: 1px solid darken($ui-base-color, 14%);
+  border-radius: 4px;
+  display: flex;
+  align-items: center;
+  padding-right: 4px;
+  position: relative;
+  top: 1px;
+  transition: border-color 300ms linear;
+
+  &__wrapper {
+    flex: 1 1 auto;
+  }
+
+  input[type=text] {
+    background: transparent;
+    border: 0;
+    padding: 10px;
+    font-size: 14px;
+    font-family: $font-monospace, monospace;
+  }
+
+  button {
+    flex: 0 0 auto;
+    margin: 4px;
+    text-transform: none;
+    font-weight: 400;
+    font-size: 14px;
+    padding: 7px 18px;
+    padding-bottom: 6px;
+    width: auto;
+    transition: background 300ms linear;
+  }
+
+  &.copied {
+    border-color: $valid-value-color;
+    transition: none;
+
+    button {
+      background: $valid-value-color;
+      transition: none;
+    }
+  }
+}
diff --git a/app/javascript/styles/mastodon/introduction.scss b/app/javascript/styles/mastodon/introduction.scss
new file mode 100644
index 0000000000000000000000000000000000000000..222d8f60e863b167b5b76326a317b1ad0792f5b4
--- /dev/null
+++ b/app/javascript/styles/mastodon/introduction.scss
@@ -0,0 +1,153 @@
+.introduction {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+
+  @media screen and (max-width: 920px) {
+    background: darken($ui-base-color, 8%);
+    display: block !important;
+  }
+
+  &__pager {
+    background: darken($ui-base-color, 8%);
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    overflow: hidden;
+  }
+
+  &__pager,
+  &__frame {
+    border-radius: 10px;
+    width: 50vw;
+    min-width: 920px;
+
+    @media screen and (max-width: 920px) {
+      min-width: 0;
+      width: 100%;
+      border-radius: 0;
+      box-shadow: none;
+    }
+  }
+
+  &__frame-wrapper {
+    opacity: 0;
+    transition: opacity 500ms linear;
+
+    &.active {
+      opacity: 1;
+      transition: opacity 50ms linear;
+    }
+  }
+
+  &__frame {
+    overflow: hidden;
+  }
+
+  &__illustration {
+    height: 50vh;
+
+    @media screen and (max-width: 630px) {
+      height: auto;
+    }
+
+    img {
+      object-fit: cover;
+      display: block;
+      margin: 0;
+      width: 100%;
+      height: 100%;
+    }
+  }
+
+  &__text {
+    border-top: 2px solid $ui-highlight-color;
+
+    &--columnized {
+      display: flex;
+
+      & > div {
+        flex: 1 1 33.33%;
+        text-align: center;
+        padding: 25px;
+        padding-bottom: 30px;
+      }
+
+      @media screen and (max-width: 630px) {
+        display: block;
+        padding: 15px 0;
+        padding-bottom: 20px;
+
+        & > div {
+          padding: 10px 25px;
+        }
+      }
+    }
+
+    h3 {
+      font-size: 24px;
+      line-height: 1.5;
+      font-weight: 700;
+      margin-bottom: 10px;
+    }
+
+    p {
+      font-size: 16px;
+      line-height: 24px;
+      font-weight: 400;
+      color: $darker-text-color;
+
+      code {
+        display: inline-block;
+        background: darken($ui-base-color, 8%);
+        font-size: 15px;
+        border: 1px solid lighten($ui-base-color, 8%);
+        border-radius: 2px;
+        padding: 1px 3px;
+      }
+    }
+
+    &--centered {
+      padding: 25px;
+      padding-bottom: 30px;
+      text-align: center;
+    }
+  }
+
+  &__dots {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 25px;
+
+    @media screen and (max-width: 630px) {
+      display: none;
+    }
+  }
+
+  &__dot {
+    width: 14px;
+    height: 14px;
+    border-radius: 14px;
+    border: 1px solid $ui-highlight-color;
+    background: transparent;
+    margin: 0 3px;
+    cursor: pointer;
+
+    &:hover {
+      background: lighten($ui-base-color, 8%);
+    }
+
+    &.active {
+      cursor: default;
+      background: $ui-highlight-color;
+    }
+  }
+
+  &__action {
+    padding: 25px;
+    padding-top: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+}
diff --git a/app/javascript/styles/mastodon/landing_strip.scss b/app/javascript/styles/mastodon/landing_strip.scss
deleted file mode 100644
index 86614b89bc5802fe91ecd41bf4b6d879236dcad8..0000000000000000000000000000000000000000
--- a/app/javascript/styles/mastodon/landing_strip.scss
+++ /dev/null
@@ -1,111 +0,0 @@
-.landing-strip,
-.memoriam-strip {
-  background: rgba(darken($ui-base-color, 7%), 0.8);
-  color: $darker-text-color;
-  font-weight: 400;
-  padding: 14px;
-  border-radius: 4px;
-  margin-bottom: 20px;
-  display: flex;
-  align-items: center;
-
-  strong,
-  a {
-    font-weight: 500;
-
-    @each $lang in $cjk-langs {
-      &:lang(#{$lang}) {
-        font-weight: 700;
-      }
-    }
-  }
-
-  a {
-    color: inherit;
-    text-decoration: underline;
-  }
-
-  .logo {
-    width: 30px;
-    height: 30px;
-    flex: 0 0 auto;
-    margin-right: 15px;
-  }
-
-  @media screen and (max-width: 740px) {
-    margin-bottom: 0;
-  }
-}
-
-.memoriam-strip {
-  background: rgba($base-shadow-color, 0.7);
-}
-
-.moved-strip {
-  padding: 14px;
-  border-radius: 4px;
-  background: rgba(darken($ui-base-color, 7%), 0.8);
-  color: $secondary-text-color;
-  font-weight: 400;
-  margin-bottom: 20px;
-
-  strong,
-  a {
-    font-weight: 500;
-
-    @each $lang in $cjk-langs {
-      &:lang(#{$lang}) {
-        font-weight: 700;
-      }
-    }
-  }
-
-  a {
-    color: inherit;
-    text-decoration: underline;
-
-    &.mention {
-      text-decoration: none;
-
-      span {
-        text-decoration: none;
-      }
-
-      &:focus,
-      &:hover,
-      &:active {
-        text-decoration: none;
-
-        span {
-          text-decoration: underline;
-        }
-      }
-    }
-  }
-
-  &__message {
-    margin-bottom: 15px;
-
-    .fa {
-      margin-right: 5px;
-      color: $darker-text-color;
-    }
-  }
-
-  &__card {
-    .detailed-status__display-avatar {
-      position: relative;
-      cursor: pointer;
-    }
-
-    .detailed-status__display-name {
-      margin-bottom: 0;
-      text-decoration: none;
-
-      span {
-        color: $highlight-text-color;
-        font-weight: 400;
-      }
-    }
-  }
-}
diff --git a/app/javascript/styles/mastodon/reset.scss b/app/javascript/styles/mastodon/reset.scss
index ff3b2c02231490ad50d6bdcedfd6251067cafe1a..e24ba8c1c015dff42f2acfd0f916cc8279b30931 100644
--- a/app/javascript/styles/mastodon/reset.scss
+++ b/app/javascript/styles/mastodon/reset.scss
@@ -53,6 +53,10 @@ table {
   border-spacing: 0;
 }
 
+html {
+  scrollbar-color: lighten($ui-base-color, 4%) transparent;
+}
+
 ::-webkit-scrollbar {
   width: 12px;
   height: 12px;
diff --git a/app/javascript/styles/mastodon/rtl.scss b/app/javascript/styles/mastodon/rtl.scss
index b8c0efad86332435bb87b647571ec2c53565ac20..940dc8af298d529f66f3f420256bc9a1d6b5dba3 100644
--- a/app/javascript/styles/mastodon/rtl.scss
+++ b/app/javascript/styles/mastodon/rtl.scss
@@ -46,8 +46,8 @@ body.rtl {
   .column-header__buttons {
     left: 0;
     right: auto;
-    margin-left: -15px;
-    margin-right: 0;
+    margin-left: 0;
+    margin-right: -15px;
   }
 
   .column-inline-form .icon-button {
@@ -73,15 +73,11 @@ body.rtl {
     float: left;
   }
 
-  .setting-toggle {
+  .setting-toggle__label {
     margin-left: 0;
     margin-right: 8px;
   }
 
-  .setting-meta__label {
-    float: left;
-  }
-
   .status__avatar {
     left: auto;
     right: 10px;
@@ -134,15 +130,17 @@ body.rtl {
     float: left;
   }
 
-  .activity-stream .detailed-status.light .detailed-status__display-name > div {
-    float: right;
-    margin-right: 0;
-    margin-left: 10px;
-  }
+  .status__action-bar {
 
-  .activity-stream .detailed-status.light .detailed-status__meta span > span {
-    margin-left: 0;
-    margin-right: 6px;
+    &__counter {
+      margin-right: 0;
+      margin-left: 11px;
+
+      .status__action-bar-button {
+        margin-right: 0;
+        margin-left: 4px;
+      }
+    }
   }
 
   .status__action-bar-button {
@@ -165,6 +163,10 @@ body.rtl {
     margin-right: 0;
   }
 
+  .detailed-status__display-name .display-name {
+    text-align: right;
+  }
+
   .detailed-status__display-avatar {
     margin-right: 0;
     margin-left: 10px;
@@ -187,40 +189,73 @@ body.rtl {
     right: -2.14285714em;
   }
 
+  .admin-wrapper {
+    direction: rtl;
+  }
+
   .admin-wrapper .sidebar ul a i.fa,
   a.table-action-link i.fa {
     margin-right: 0;
     margin-left: 5px;
   }
 
-  .simple_form .check_boxes .checkbox label,
-  .simple_form .input.with_label.boolean label.checkbox {
+  .simple_form .check_boxes .checkbox label {
     padding-left: 0;
     padding-right: 25px;
   }
 
+  .simple_form .input.with_label.boolean label.checkbox {
+    padding-left: 25px;
+    padding-right: 0;
+  }
+
   .simple_form .check_boxes .checkbox input[type="checkbox"],
   .simple_form .input.boolean input[type="checkbox"] {
     left: auto;
     right: 0;
   }
 
+  .simple_form .input.radio_buttons .radio {
+    left: auto;
+    right: 0;
+  }
+
+  .simple_form .input.radio_buttons .radio > label {
+    padding-right: 28px;
+    padding-left: 0;
+  }
+
   .simple_form .input-with-append .input input {
     padding-left: 142px;
     padding-right: 0;
   }
 
-  .simple_form .input-with-append .append {
+  .simple_form .input.boolean label.checkbox {
+    left: auto;
+    right: 0;
+  }
+
+  .simple_form .input.boolean .label_input,
+  .simple_form .input.boolean .hint {
+    padding-left: 0;
+    padding-right: 28px;
+  }
+
+  .simple_form .label_input__append {
     right: auto;
-    left: 0;
+    left: 3px;
 
     &::after {
       right: auto;
       left: 0;
-      background-image: linear-gradient(to left, rgba($ui-base-color, 0), $ui-base-color);
+      background-image: linear-gradient(to left, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%));
     }
   }
 
+  .simple_form select {
+    background: darken($ui-base-color, 10%) 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, 12%))}'/></svg>") no-repeat left 8px center / auto 16px;
+  }
+
   .table th,
   .table td {
     text-align: right;
@@ -236,6 +271,10 @@ body.rtl {
     left: auto;
   }
 
+  .landing-page__call-to-action .row__information-board {
+    direction: rtl;
+  }
+
   .landing-page .header .hero .floats .float-1 {
     left: -120px;
     right: auto;
@@ -285,4 +324,59 @@ body.rtl {
       }
     }
   }
+
+  .public-layout {
+    .header {
+      .nav-button {
+        margin-left: 8px;
+        margin-right: 0;
+      }
+    }
+
+    .public-account-header__tabs {
+      margin-left: 0;
+      margin-right: 20px;
+    }
+  }
+
+  .landing-page__information {
+    .account__display-name {
+      margin-right: 0;
+      margin-left: 5px;
+    }
+
+    .account__avatar-wrapper {
+      margin-left: 12px;
+      margin-right: 0;
+    }
+  }
+
+  .card__bar .display-name {
+    margin-left: 0;
+    margin-right: 15px;
+    text-align: right;
+  }
+
+  .fa-chevron-left::before {
+    content: "\F054";
+  }
+
+  .fa-chevron-right::before {
+    content: "\F053";
+  }
+
+  .column-back-button__icon {
+    margin-right: 0;
+    margin-left: 5px;
+  }
+
+  .column-header__setting-arrows .column-header__setting-btn:last-child {
+    padding-left: 0;
+    padding-right: 10px;
+  }
+
+  .simple_form .input.radio_buttons .radio > label input {
+    left: auto;
+    right: 0;
+  }
 }
diff --git a/app/javascript/styles/mastodon/stream_entries.scss b/app/javascript/styles/mastodon/stream_entries.scss
index 9188c22064e69cad315f8f7e1b26856438aa7d7c..d8bd30377286e1af43766e17eaccf0c8a6da55c4 100644
--- a/app/javascript/styles/mastodon/stream_entries.scss
+++ b/app/javascript/styles/mastodon/stream_entries.scss
@@ -1,363 +1,165 @@
 .activity-stream {
-  clear: both;
   box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+  border-radius: 4px;
+  overflow: hidden;
+  margin-bottom: 10px;
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-bottom: 0;
+    border-radius: 0;
+    box-shadow: none;
+  }
+
+  &--headless {
+    border-radius: 0;
+    margin: 0;
+    box-shadow: none;
+
+    .detailed-status,
+    .status {
+      border-radius: 0 !important;
+    }
+  }
+
+  div[data-component] {
+    width: 100%;
+  }
 
   .entry {
-    background: $simple-background-color;
+    background: $ui-base-color;
 
-    .detailed-status.light,
-    .status.light,
-    .more.light {
-      border-bottom: 1px solid $ui-secondary-color;
+    .detailed-status,
+    .status,
+    .load-more {
       animation: none;
     }
 
     &:last-child {
-      &,
-      .detailed-status.light,
-      .status.light {
+      .detailed-status,
+      .status,
+      .load-more {
         border-bottom: 0;
         border-radius: 0 0 4px 4px;
       }
     }
 
     &:first-child {
-      &,
-      .detailed-status.light,
-      .status.light {
+      .detailed-status,
+      .status,
+      .load-more {
         border-radius: 4px 4px 0 0;
       }
 
       &:last-child {
-        &,
-        .detailed-status.light,
-        .status.light {
+        .detailed-status,
+        .status,
+        .load-more {
           border-radius: 4px;
         }
       }
     }
 
     @media screen and (max-width: 740px) {
-      &,
-      .detailed-status.light,
-      .status.light {
+      .detailed-status,
+      .status,
+      .load-more {
         border-radius: 0 !important;
       }
     }
   }
 
-  &.with-header {
-    .entry {
-      &:first-child {
-        &,
-        .detailed-status.light,
-        .status.light {
-          border-radius: 0;
-        }
-
-        &:last-child {
-          &,
-          .detailed-status.light,
-          .status.light {
-            border-radius: 0 0 4px 4px;
-          }
-        }
-      }
-    }
-  }
-
-  .media-gallery__gifv__label {
-    bottom: 9px;
-  }
-
-  .status.light {
-    padding: 14px 14px 14px (48px + 14px * 2);
-    position: relative;
-    min-height: 48px;
-    cursor: default;
-
-    .status__header {
-      font-size: 15px;
-
-      .status__meta {
-        float: right;
-        font-size: 14px;
-
-        .status__relative-time {
-          color: $lighter-text-color;
-        }
-      }
-    }
-
-    .status__display-name {
-      display: block;
-      max-width: 100%;
-      padding-right: 25px;
-      color: $inverted-text-color;
-    }
-
-    .status__avatar {
-      position: absolute;
-      left: 14px;
-      top: 14px;
-      width: 48px;
-      height: 48px;
-
-      & > div {
-        width: 48px;
-        height: 48px;
-      }
-
-      img {
-        display: block;
-        border-radius: 4px;
-      }
-    }
-
-    .display-name {
-      display: block;
-      max-width: 100%;
-      overflow: hidden;
-      white-space: nowrap;
-      text-overflow: ellipsis;
-
-      strong {
-        font-weight: 500;
-        color: $inverted-text-color;
-
-        @each $lang in $cjk-langs {
-          &:lang(#{$lang}) {
-            font-weight: 700;
-          }
-        }
-      }
-
-      span {
-        font-size: 14px;
-        color: $light-text-color;
-      }
-    }
-
-    .status__content {
-      color: $inverted-text-color;
-
-      a {
-        color: $highlight-text-color;
-      }
-
-      a.status__content__spoiler-link {
-        color: $primary-text-color;
-        background: $ui-base-color;
-
-        &:hover {
-          background: lighten($ui-base-color, 8%);
-        }
-      }
-    }
+  &--highlighted .entry {
+    background: lighten($ui-base-color, 8%);
   }
+}
 
-  .detailed-status.light {
-    padding: 14px;
-    background: $simple-background-color;
-    cursor: default;
-
-    .detailed-status__display-name {
-      display: block;
-      overflow: hidden;
-      margin-bottom: 15px;
-
-      & > div {
-        float: left;
-        margin-right: 10px;
-      }
-
-      .display-name {
-        display: block;
-        max-width: 100%;
-        overflow: hidden;
-        white-space: nowrap;
-        text-overflow: ellipsis;
-
-        strong {
-          font-weight: 500;
-          color: $inverted-text-color;
-
-          @each $lang in $cjk-langs {
-            &:lang(#{$lang}) {
-              font-weight: 700;
-            }
-          }
-        }
-
-        span {
-          font-size: 14px;
-          color: $light-text-color;
-        }
-      }
-    }
-
-    .avatar {
-      width: 48px;
-      height: 48px;
-
-      img {
-        display: block;
-        border-radius: 4px;
-      }
-    }
-
-    .status__content {
-      color: $inverted-text-color;
-
-      a {
-        color: $highlight-text-color;
-      }
-
-      a.status__content__spoiler-link {
-        color: $primary-text-color;
-        background: $ui-base-color;
-
-        &:hover {
-          background: lighten($ui-base-color, 8%);
-        }
-      }
-    }
-
-    .detailed-status__meta {
-      margin-top: 15px;
-      color: $light-text-color;
-      font-size: 14px;
-      line-height: 18px;
-
-      a {
-        color: inherit;
-      }
-
-      span > span {
-        font-weight: 500;
-        font-size: 12px;
-        margin-left: 6px;
-        display: inline-block;
-      }
-    }
-
-    .status-card {
-      border-color: lighten($ui-secondary-color, 4%);
-      color: $lighter-text-color;
+.button.logo-button {
+  flex: 0 auto;
+  font-size: 14px;
+  background: $ui-highlight-color;
+  color: $primary-text-color;
+  text-transform: none;
+  line-height: 36px;
+  height: auto;
+  padding: 3px 15px;
+  border: 0;
 
-      &:hover {
-        background: lighten($ui-secondary-color, 4%);
-      }
-    }
+  svg {
+    width: 20px;
+    height: auto;
+    vertical-align: middle;
+    margin-right: 5px;
 
-    .status-card__title,
-    .status-card__description {
-      color: $inverted-text-color;
+    path:first-child {
+      fill: $primary-text-color;
     }
 
-    .status-card__image {
-      background: $ui-secondary-color;
+    path:last-child {
+      fill: $ui-highlight-color;
     }
   }
 
-  .media-spoiler {
-    background: $ui-base-color;
-    color: $darker-text-color;
-  }
+  &:active,
+  &:focus,
+  &:hover {
+    background: lighten($ui-highlight-color, 10%);
 
-  .pre-header {
-    padding: 14px 0;
-    padding-left: (48px + 14px * 2);
-    padding-bottom: 0;
-    margin-bottom: -4px;
-    color: $light-text-color;
-    font-size: 14px;
-    position: relative;
-
-    .pre-header__icon {
-      position: absolute;
-      left: (48px + 14px * 2 - 30px);
-    }
-
-    .status__display-name.muted strong {
-      color: $light-text-color;
+    svg path:last-child {
+      fill: lighten($ui-highlight-color, 10%);
     }
   }
 
-  .open-in-web-link {
-    text-decoration: none;
-
+  &.button--destructive {
+    &:active,
+    &:focus,
     &:hover {
-      text-decoration: underline;
+      background: $error-red;
+
+      svg path:last-child {
+        fill: $error-red;
+      }
     }
   }
 
-  .more {
-    color: $darker-text-color;
-    display: block;
-    padding: 14px;
-    text-align: center;
-
-    &:not(:hover) {
-      text-decoration: none;
+  @media screen and (max-width: $no-gap-breakpoint) {
+    svg {
+      display: none;
     }
   }
 }
 
-.embed {
-  .activity-stream {
-    box-shadow: none;
+.embed,
+.public-layout {
+  .detailed-status {
+    padding: 15px;
   }
-}
 
-.entry {
-  .detailed-status.light {
-    display: flex;
-    flex-wrap: wrap;
-    justify-content: space-between;
-    align-items: flex-start;
+  .status {
+    padding: 15px 15px 15px (48px + 15px * 2);
+    min-height: 48px + 2px;
 
-    .detailed-status__display-name {
-      flex: 1;
-      margin: 0 5px 15px 0;
+    &__avatar {
+      left: 15px;
+      top: 17px;
     }
 
-    .button.button-secondary.logo-button {
-      flex: 0 auto;
-      font-size: 14px;
-      background: $ui-highlight-color;
-      color: $primary-text-color;
-      border: 0;
-
-      svg {
-        width: 20px;
-        height: auto;
-        vertical-align: middle;
-        margin-right: 5px;
-
-        path:first-child {
-          fill: $primary-text-color;
-        }
-
-        path:last-child {
-          fill: $ui-highlight-color;
-        }
-      }
+    &__content {
+      padding-top: 5px;
+    }
 
-      &:active,
-      &:focus,
-      &:hover {
-        background: lighten($ui-highlight-color, 10%);
+    &__prepend {
+      margin-left: 48px + 15px * 2;
+      padding-top: 15px;
+    }
 
-        svg path:last-child {
-          fill: lighten($ui-highlight-color, 10%);
-        }
-      }
+    &__prepend-icon-wrapper {
+      left: -32px;
     }
 
-    .status__content,
-    .detailed-status__meta {
-      flex: 100%;
+    .media-gallery,
+    &__action-bar,
+    .video-player {
+      margin-top: 10px;
     }
   }
 }
diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss
index e54c55947e63b3ea0810a20497c503fedcaf4f7d..adb75afe5bdf3f361e8a5a14ce4542f084fd5844 100644
--- a/app/javascript/styles/mastodon/tables.scss
+++ b/app/javascript/styles/mastodon/tables.scss
@@ -1,9 +1,3 @@
-@keyframes Swag {
-  0% { background-position: 0% 0%; }
-  50% { background-position: 100% 0%; }
-  100% { background-position: 200% 0%; }
-}
-
 .table {
   width: 100%;
   max-width: 100%;
@@ -96,7 +90,7 @@
 }
 
 samp {
-  font-family: 'mastodon-font-monospace', monospace;
+  font-family: $font-monospace, monospace;
 }
 
 button.table-action-link {
@@ -191,14 +185,12 @@ a.table-action-link {
   .status__content {
     padding-top: 0;
 
+    summary {
+      display: list-item;
+    }
+
     strong {
       font-weight: 700;
-      background: linear-gradient(to right, orange , yellow, green, cyan, blue, violet,orange , yellow, green, cyan, blue, violet);
-      background-size: 200% 100%;
-      -webkit-background-clip: text;
-      background-clip: text;
-      color: transparent;
-      animation: Swag 2s linear 0s infinite;
     }
   }
 }
diff --git a/app/javascript/styles/mastodon/variables.scss b/app/javascript/styles/mastodon/variables.scss
index 40aeb4afcfe2cd41654ef82403300ad243ee0bea..a82c44229639dac104e53e8f11452f094a1c8e96 100644
--- a/app/javascript/styles/mastodon/variables.scss
+++ b/app/javascript/styles/mastodon/variables.scss
@@ -46,3 +46,9 @@ $cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
 $media-modal-media-max-width: 100%;
 // put margins on top and bottom of image to avoid the screen covered by image.
 $media-modal-media-max-height: 80%;
+
+$no-gap-breakpoint: 415px;
+
+$font-sans-serif: 'mastodon-font-sans-serif' !default;
+$font-display: 'mastodon-font-display' !default;
+$font-monospace: 'mastodon-font-monospace' !default;
diff --git a/app/javascript/styles/mastodon/widgets.scss b/app/javascript/styles/mastodon/widgets.scss
new file mode 100644
index 0000000000000000000000000000000000000000..c97337e4e3f77c837dd15b7a1f77df44133b92f6
--- /dev/null
+++ b/app/javascript/styles/mastodon/widgets.scss
@@ -0,0 +1,517 @@
+.hero-widget {
+  margin-bottom: 10px;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+
+  &__img {
+    width: 100%;
+    height: 167px;
+    position: relative;
+    overflow: hidden;
+    border-radius: 4px 4px 0 0;
+    background: $base-shadow-color;
+
+    img {
+      object-fit: cover;
+      display: block;
+      width: 100%;
+      height: 100%;
+      margin: 0;
+      border-radius: 4px 4px 0 0;
+    }
+  }
+
+  &__text {
+    background: $ui-base-color;
+    padding: 20px;
+    border-radius: 0 0 4px 4px;
+    font-size: 15px;
+    color: $darker-text-color;
+    line-height: 20px;
+    word-wrap: break-word;
+    font-weight: 400;
+
+    .emojione {
+      width: 20px;
+      height: 20px;
+      margin: -3px 0 0;
+    }
+
+    p {
+      margin-bottom: 20px;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+
+    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%);
+    }
+
+    a {
+      color: $secondary-text-color;
+      text-decoration: none;
+
+      &:hover {
+        text-decoration: underline;
+      }
+    }
+  }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    display: none;
+  }
+}
+
+.endorsements-widget {
+  margin-bottom: 10px;
+  padding-bottom: 10px;
+
+  h4 {
+    padding: 10px;
+    text-transform: uppercase;
+    font-weight: 700;
+    font-size: 13px;
+    color: $darker-text-color;
+  }
+
+  .account {
+    padding: 10px 0;
+
+    &:last-child {
+      border-bottom: 0;
+    }
+
+    .account__display-name {
+      display: flex;
+      align-items: center;
+    }
+
+    .account__avatar {
+      width: 44px;
+      height: 44px;
+      background-size: 44px 44px;
+    }
+  }
+}
+
+.box-widget {
+  padding: 20px;
+  border-radius: 4px;
+  background: $ui-base-color;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+}
+
+.contact-widget,
+.landing-page__information.contact-widget {
+  box-sizing: border-box;
+  padding: 20px;
+  min-height: 100%;
+  border-radius: 4px;
+  background: $ui-base-color;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+}
+
+.contact-widget {
+  font-size: 15px;
+  color: $darker-text-color;
+  line-height: 20px;
+  word-wrap: break-word;
+  font-weight: 400;
+
+  strong {
+    font-weight: 500;
+  }
+
+  p {
+    margin-bottom: 10px;
+
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+
+  &__mail {
+    margin-top: 10px;
+
+    a {
+      color: $primary-text-color;
+      text-decoration: none;
+    }
+  }
+}
+
+.moved-account-widget {
+  padding: 15px;
+  padding-bottom: 20px;
+  border-radius: 4px;
+  background: $ui-base-color;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+  color: $secondary-text-color;
+  font-weight: 400;
+  margin-bottom: 10px;
+
+  strong,
+  a {
+    font-weight: 500;
+
+    @each $lang in $cjk-langs {
+      &:lang(#{$lang}) {
+        font-weight: 700;
+      }
+    }
+  }
+
+  a {
+    color: inherit;
+    text-decoration: underline;
+
+    &.mention {
+      text-decoration: none;
+
+      span {
+        text-decoration: none;
+      }
+
+      &:focus,
+      &:hover,
+      &:active {
+        text-decoration: none;
+
+        span {
+          text-decoration: underline;
+        }
+      }
+    }
+  }
+
+  &__message {
+    margin-bottom: 15px;
+
+    .fa {
+      margin-right: 5px;
+      color: $darker-text-color;
+    }
+  }
+
+  &__card {
+    .detailed-status__display-avatar {
+      position: relative;
+      cursor: pointer;
+    }
+
+    .detailed-status__display-name {
+      margin-bottom: 0;
+      text-decoration: none;
+
+      span {
+        font-weight: 400;
+      }
+    }
+  }
+}
+
+.memoriam-widget {
+  padding: 20px;
+  border-radius: 4px;
+  background: $base-shadow-color;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+  font-size: 14px;
+  color: $darker-text-color;
+  margin-bottom: 10px;
+}
+
+.page-header {
+  background: lighten($ui-base-color, 8%);
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+  border-radius: 4px;
+  padding: 60px 15px;
+  text-align: center;
+  margin: 10px 0;
+
+  h1 {
+    color: $primary-text-color;
+    font-size: 36px;
+    line-height: 1.1;
+    font-weight: 700;
+    margin-bottom: 10px;
+  }
+
+  p {
+    font-size: 15px;
+    color: $darker-text-color;
+  }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-top: 0;
+    background: lighten($ui-base-color, 4%);
+
+    h1 {
+      font-size: 24px;
+    }
+  }
+}
+
+.directory {
+  background: $ui-base-color;
+  border-radius: 4px;
+  box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+
+  &__tag {
+    box-sizing: border-box;
+    margin-bottom: 10px;
+
+    a {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      background: $ui-base-color;
+      border-radius: 4px;
+      padding: 15px;
+      text-decoration: none;
+      color: inherit;
+      box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+
+      &:hover,
+      &:active,
+      &:focus {
+        background: lighten($ui-base-color, 8%);
+      }
+    }
+
+    &.active a {
+      background: $ui-highlight-color;
+      cursor: default;
+    }
+
+    h4 {
+      flex: 1 1 auto;
+      font-size: 18px;
+      font-weight: 700;
+      color: $primary-text-color;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+
+      .fa {
+        color: $darker-text-color;
+      }
+
+      small {
+        display: block;
+        font-weight: 400;
+        font-size: 15px;
+        margin-top: 8px;
+        color: $darker-text-color;
+      }
+    }
+
+    &.active h4 {
+      &,
+      .fa,
+      small {
+        color: $primary-text-color;
+      }
+    }
+
+    .avatar-stack {
+      flex: 0 0 auto;
+      width: (36px + 4px) * 3;
+    }
+
+    &.active .avatar-stack .account__avatar {
+      border-color: $ui-highlight-color;
+    }
+  }
+}
+
+.avatar-stack {
+  display: flex;
+  justify-content: flex-end;
+
+  .account__avatar {
+    flex: 0 0 auto;
+    width: 36px;
+    height: 36px;
+    border-radius: 50%;
+    position: relative;
+    margin-left: -10px;
+    border: 2px solid $ui-base-color;
+
+    &:nth-child(1) {
+      z-index: 1;
+    }
+
+    &:nth-child(2) {
+      z-index: 2;
+    }
+
+    &:nth-child(3) {
+      z-index: 3;
+    }
+  }
+}
+
+.accounts-table {
+  width: 100%;
+
+  .account {
+    padding: 0;
+    border: 0;
+  }
+
+  thead th {
+    text-align: center;
+    text-transform: uppercase;
+    color: $darker-text-color;
+    font-weight: 700;
+    padding: 10px;
+
+    &:first-child {
+      text-align: left;
+    }
+  }
+
+  tbody td {
+    padding: 15px 0;
+    vertical-align: middle;
+    border-bottom: 1px solid lighten($ui-base-color, 8%);
+  }
+
+  tbody tr:last-child td {
+    border-bottom: 0;
+  }
+
+  &__count {
+    width: 120px;
+    text-align: center;
+    font-size: 15px;
+    font-weight: 500;
+    color: $primary-text-color;
+
+    small {
+      display: block;
+      color: $darker-text-color;
+      font-weight: 400;
+      font-size: 14px;
+    }
+  }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    tbody td.optional {
+      display: none;
+    }
+  }
+}
+
+.moved-account-widget,
+.memoriam-widget,
+.box-widget,
+.contact-widget,
+.landing-page__information.contact-widget,
+.directory,
+.page-header {
+  @media screen and (max-width: $no-gap-breakpoint) {
+    margin-bottom: 0;
+    box-shadow: none;
+    border-radius: 0;
+  }
+}
+
+$maximum-width: 1235px;
+$fluid-breakpoint: $maximum-width + 20px;
+
+.statuses-grid {
+  min-height: 600px;
+
+  @media screen and (max-width: 640px) {
+    width: 100% !important; // Masonry layout is unnecessary at this width
+  }
+
+  &__item {
+    width: (960px - 20px) / 3;
+
+    @media screen and (max-width: $fluid-breakpoint) {
+      width: (940px - 20px) / 3;
+    }
+
+    @media screen and (max-width: 640px) {
+      width: 100%;
+    }
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      width: 100vw;
+    }
+  }
+
+  .detailed-status {
+    border-radius: 4px;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-top: 1px solid lighten($ui-base-color, 16%);
+    }
+
+    &.compact {
+      .detailed-status__meta {
+        margin-top: 15px;
+      }
+
+      .status__content {
+        font-size: 15px;
+        line-height: 20px;
+
+        .emojione {
+          width: 20px;
+          height: 20px;
+          margin: -3px 0 0;
+        }
+
+        .status__content__spoiler-link {
+          line-height: 20px;
+          margin: 0;
+        }
+      }
+
+      .media-gallery,
+      .status-card,
+      .video-player {
+        margin-top: 15px;
+      }
+    }
+  }
+}
+
+.notice-widget {
+  margin-bottom: 10px;
+  color: $darker-text-color;
+
+  p {
+    margin-bottom: 10px;
+
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+
+  a {
+    font-size: 14px;
+    line-height: 20px;
+    text-decoration: none;
+    font-weight: 500;
+    color: $ui-highlight-color;
+
+    &:hover,
+    &:focus,
+    &:active {
+      text-decoration: underline;
+    }
+  }
+}
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb
index 03476920b265adac918cd91254c3506e9192cceb..87318fb1c5c33b9fb977e285b4cac5f9a082e7bf 100644
--- a/app/lib/activitypub/activity.rb
+++ b/app/lib/activitypub/activity.rb
@@ -50,6 +50,8 @@ class ActivityPub::Activity
         ActivityPub::Activity::Add
       when 'Remove'
         ActivityPub::Activity::Remove
+      when 'Move'
+        ActivityPub::Activity::Move
       end
     end
   end
@@ -96,7 +98,7 @@ class ActivityPub::Activity
   end
 
   def notify_about_mentions(status)
-    status.mentions.includes(:account).each do |mention|
+    status.active_mentions.includes(:account).each do |mention|
       next unless mention.account.local? && audience_includes?(mention.account)
       NotifyService.new.call(mention.account, mention)
     end
@@ -104,7 +106,9 @@ class ActivityPub::Activity
 
   def crawl_links(status)
     return if status.spoiler_text?
-    LinkCrawlWorker.perform_async(status.id)
+
+    # Spread out crawling randomly to avoid DDoSing the link
+    LinkCrawlWorker.perform_in(rand(1..59).seconds, status.id)
   end
 
   def distribute_to_followers(status)
@@ -127,4 +131,10 @@ class ActivityPub::Activity
       ::FetchRemoteStatusService.new.call(@object['url'])
     end
   end
+
+  def lock_or_return(key, expire_after = 7.days.seconds)
+    yield if redis.set(key, true, nx: true, ex: expire_after)
+  ensure
+    redis.del(key)
+  end
 end
diff --git a/app/lib/activitypub/activity/accept.rb b/app/lib/activitypub/activity/accept.rb
index bd90c901944f08ed3ff4ce46b9578d20cc98d13a..348ee0d1cb3ef27ea9ccc559c18fc2ac8dadb3a7 100644
--- a/app/lib/activitypub/activity/accept.rb
+++ b/app/lib/activitypub/activity/accept.rb
@@ -11,6 +11,8 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
   private
 
   def accept_follow
+    return accept_follow_for_relay if relay_follow?
+
     target_account = account_from_uri(target_uri)
 
     return if target_account.nil? || !target_account.local?
@@ -19,6 +21,18 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
     follow_request&.authorize!
   end
 
+  def accept_follow_for_relay
+    relay.update!(state: :accepted)
+  end
+
+  def relay
+    @relay ||= Relay.find_by(follow_activity_id: object_uri) unless object_uri.nil?
+  end
+
+  def relay_follow?
+    relay.present?
+  end
+
   def target_uri
     @target_uri ||= value_or_id(@object['actor'])
   end
diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb
index 1147a4481fd02466ae01d7322ed79bfbba434224..34d1b7cbd0fe1f04f1a5fda453f1f95056e9a6a2 100644
--- a/app/lib/activitypub/activity/announce.rb
+++ b/app/lib/activitypub/activity/announce.rb
@@ -17,7 +17,7 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
       uri: @json['id'],
       created_at: @json['published'],
       override_timestamps: @options[:override_timestamps],
-      visibility: original_status.visibility
+      visibility: visibility_from_audience
     )
 
     distribute(status)
@@ -26,6 +26,18 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
 
   private
 
+  def visibility_from_audience
+    if equals_or_includes?(@json['to'], ActivityPub::TagManager::COLLECTIONS[:public])
+      :public
+    elsif equals_or_includes?(@json['cc'], ActivityPub::TagManager::COLLECTIONS[:public])
+      :unlisted
+    elsif equals_or_includes?(@json['to'], @account.followers_url)
+      :private
+    else
+      :direct
+    end
+  end
+
   def announceable?(status)
     status.account_id == @account.id || status.public_visibility? || status.unlisted_visibility?
   end
diff --git a/app/lib/activitypub/activity/block.rb b/app/lib/activitypub/activity/block.rb
index 26da8bdf5c46edf16b53b2946d19b137d3cd90fe..a17a2d50a6af0a738b2c36f41bae3afa5dcf309a 100644
--- a/app/lib/activitypub/activity/block.rb
+++ b/app/lib/activitypub/activity/block.rb
@@ -4,9 +4,10 @@ class ActivityPub::Activity::Block < ActivityPub::Activity
   def perform
     target_account = account_from_uri(object_uri)
 
-    return if target_account.nil? || !target_account.local? || delete_arrived_first?(@json['id']) || @account.blocking?(target_account)
+    return if target_account.nil? || !target_account.local? || @account.blocking?(target_account)
 
     UnfollowService.new.call(target_account, @account) if target_account.following?(@account)
-    @account.block!(target_account, uri: @json['id'])
+
+    @account.block!(target_account, uri: @json['id']) unless delete_arrived_first?(@json['id'])
   end
 end
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 00479fd9a5ddff1b5f8e587c3fee858aa09b34cc..b49657d4b14625238630ae3b2c07956f90a6225e 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -2,15 +2,23 @@
 
 class ActivityPub::Activity::Create < ActivityPub::Activity
   SUPPORTED_TYPES = %w(Note).freeze
-  CONVERTED_TYPES = %w(Image Video Article).freeze
+  CONVERTED_TYPES = %w(Image Video Article Page).freeze
 
   def perform
-    return if delete_arrived_first?(object_uri) || unsupported_object_type? || invalid_origin?(@object['id'])
+    return if unsupported_object_type? || invalid_origin?(@object['id'])
+    return if Tombstone.exists?(uri: @object['id'])
 
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
+        return if delete_arrived_first?(object_uri)
+
         @status = find_existing_status
-        process_status if @status.nil?
+
+        if @status.nil?
+          process_status
+        elsif @options[:delivered_to_account_id].present?
+          postprocess_audience_and_deliver
+        end
       else
         raise Mastodon::RaceConditionError
       end
@@ -22,12 +30,17 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
   private
 
   def process_status
-    status_params = process_status_params
+    @tags     = []
+    @mentions = []
+    @params   = {}
 
-    ApplicationRecord.transaction do
-      @status = Status.create!(status_params)
+    process_status_params
+    process_tags
+    process_audience
 
-      process_tags(@status)
+    ApplicationRecord.transaction do
+      @status = Status.create!(@params)
+      attach_tags(@status)
     end
 
     resolve_thread(@status)
@@ -42,62 +55,122 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
   end
 
   def process_status_params
-    {
-      uri: @object['id'],
-      url: object_url || @object['id'],
-      account: @account,
-      text: text_from_content || '',
-      language: detected_language,
-      spoiler_text: @object['summary'] || '',
-      created_at: @object['published'],
-      override_timestamps: @options[:override_timestamps],
-      reply: @object['inReplyTo'].present?,
-      sensitive: @object['sensitive'] || false,
-      visibility: visibility_from_audience,
-      thread: replied_to_status,
-      conversation: conversation_from_uri(@object['conversation']),
-      media_attachment_ids: process_attachments.take(4).map(&:id),
-    }
-  end
-
-  def process_tags(status)
+    @params = begin
+      {
+        uri: @object['id'],
+        url: object_url || @object['id'],
+        account: @account,
+        text: text_from_content || '',
+        language: detected_language,
+        spoiler_text: converted_object_type? ? '' : (text_from_summary || ''),
+        created_at: @object['published'],
+        override_timestamps: @options[:override_timestamps],
+        reply: @object['inReplyTo'].present?,
+        sensitive: @object['sensitive'] || false,
+        visibility: visibility_from_audience,
+        thread: replied_to_status,
+        conversation: conversation_from_uri(@object['conversation']),
+        media_attachment_ids: process_attachments.take(4).map(&:id),
+      }
+    end
+  end
+
+  def process_audience
+    (as_array(@object['to']) + as_array(@object['cc'])).uniq.each do |audience|
+      next if audience == ActivityPub::TagManager::COLLECTIONS[:public]
+
+      # Unlike with tags, there is no point in resolving accounts we don't already
+      # know here, because silent mentions would only be used for local access
+      # control anyway
+      account = account_from_uri(audience)
+
+      next if account.nil? || @mentions.any? { |mention| mention.account_id == account.id }
+
+      @mentions << Mention.new(account: account, silent: true)
+
+      # If there is at least one silent mention, then the status can be considered
+      # as a limited-audience status, and not strictly a direct message, but only
+      # if we considered a direct message in the first place
+      next unless @params[:visibility] == :direct
+
+      @params[:visibility] = :limited
+    end
+
+    # If the payload was delivered to a specific inbox, the inbox owner must have
+    # access to it, unless they already have access to it anyway
+    return if @options[:delivered_to_account_id].nil? || @mentions.any? { |mention| mention.account_id == @options[:delivered_to_account_id] }
+
+    @mentions << Mention.new(account_id: @options[:delivered_to_account_id], silent: true)
+
+    return unless @params[:visibility] == :direct
+
+    @params[:visibility] = :limited
+  end
+
+  def postprocess_audience_and_deliver
+    return if @status.mentions.find_by(account_id: @options[:delivered_to_account_id])
+
+    delivered_to_account = Account.find(@options[:delivered_to_account_id])
+
+    @status.mentions.create(account: delivered_to_account, silent: true)
+    @status.update(visibility: :limited) if @status.direct_visibility?
+
+    return unless delivered_to_account.following?(@account)
+
+    FeedInsertWorker.perform_async(@status.id, delivered_to_account.id, :home)
+  end
+
+  def attach_tags(status)
+    @tags.each do |tag|
+      status.tags << tag
+      TrendingTags.record_use!(tag, status.account, status.created_at) if status.public_visibility?
+    end
+
+    @mentions.each do |mention|
+      mention.status = status
+      mention.save
+    end
+  end
+
+  def process_tags
     return if @object['tag'].nil?
 
     as_array(@object['tag']).each do |tag|
       if equals_or_includes?(tag['type'], 'Hashtag')
-        process_hashtag tag, status
+        process_hashtag tag
       elsif equals_or_includes?(tag['type'], 'Mention')
-        process_mention tag, status
+        process_mention tag
       elsif equals_or_includes?(tag['type'], 'Emoji')
-        process_emoji tag, status
+        process_emoji tag
       end
     end
   end
 
-  def process_hashtag(tag, status)
+  def process_hashtag(tag)
     return if tag['name'].blank?
 
     hashtag = tag['name'].gsub(/\A#/, '').mb_chars.downcase
-    hashtag = Tag.where(name: hashtag).first_or_create(name: hashtag)
+    hashtag = Tag.where(name: hashtag).first_or_create!(name: hashtag)
 
-    return if status.tags.include?(hashtag)
+    return if @tags.include?(hashtag)
 
-    status.tags << hashtag
-    TrendingTags.record_use!(hashtag, status.account, status.created_at) if status.public_visibility?
+    @tags << hashtag
   rescue ActiveRecord::RecordInvalid
     nil
   end
 
-  def process_mention(tag, status)
+  def process_mention(tag)
     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'], id: false) if account.nil?
+
     return if account.nil?
-    account.mentions.create(status: status)
+
+    @mentions << Mention.new(account: account, silent: false)
   end
 
-  def process_emoji(tag, _status)
+  def process_emoji(tag)
     return if skip_download?
     return if tag['name'].blank? || tag['icon'].blank? || tag['icon']['url'].blank?
 
@@ -107,7 +180,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     updated   = tag['updated']
     emoji     = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain)
 
-    return unless emoji.nil? || emoji.updated_at >= updated
+    return unless emoji.nil? || image_url != emoji.image_remote_url || (updated && updated >= emoji.updated_at)
 
     emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: shortcode, uri: uri)
     emoji.image_remote_url = image_url
@@ -140,7 +213,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
   end
 
   def resolve_thread(status)
-    return unless status.reply? && status.thread.nil?
+    return unless status.reply? && status.thread.nil? && Request.valid_url?(in_reply_to_uri)
     ThreadResolveWorker.perform_async(status.id, in_reply_to_uri)
   end
 
@@ -184,7 +257,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
   end
 
   def text_from_content
-    return Formatter.instance.linkify([text_from_name, object_url || @object['id']].join(' ')) if converted_object_type?
+    return Formatter.instance.linkify([[text_from_name, text_from_summary.presence].compact.join("\n\n"), object_url || @object['id']].join(' ')) if converted_object_type?
 
     if @object['content'].present?
       @object['content']
@@ -193,6 +266,14 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     end
   end
 
+  def text_from_summary
+    if @object['summary'].present?
+      @object['summary']
+    elsif summary_language_map?
+      @object['summaryMap'].values.first
+    end
+  end
+
   def text_from_name
     if @object['name'].present?
       @object['name']
@@ -206,6 +287,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
       @object['contentMap'].keys.first
     elsif name_language_map?
       @object['nameMap'].keys.first
+    elsif summary_language_map?
+      @object['summaryMap'].keys.first
     elsif supported_object_type?
       LanguageDetector.instance.detect(text_from_content, @account)
     end
@@ -223,6 +306,10 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     end
   end
 
+  def summary_language_map?
+    @object['summaryMap'].is_a?(Hash) && !@object['summaryMap'].empty?
+  end
+
   def content_language_map?
     @object['contentMap'].is_a?(Hash) && !@object['contentMap'].empty?
   end
diff --git a/app/lib/activitypub/activity/delete.rb b/app/lib/activitypub/activity/delete.rb
index 3474d55d94735f161059f72a8390fba3a56ba3cf..dc76dd3e222ca3e8fd07816d4df4c8530f038121 100644
--- a/app/lib/activitypub/activity/delete.rb
+++ b/app/lib/activitypub/activity/delete.rb
@@ -12,16 +12,23 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
   private
 
   def delete_person
-    SuspendAccountService.new.call(@account)
-    @account.destroy!
+    lock_or_return("delete_in_progress:#{@account.id}") do
+      SuspendAccountService.new.call(@account)
+      @account.destroy!
+    end
   end
 
   def delete_note
+    return if object_uri.nil?
+
+    unless invalid_origin?(object_uri)
+      RedisLock.acquire(lock_options) { |_lock| delete_later!(object_uri) }
+      Tombstone.find_or_create_by(uri: object_uri, account: @account)
+    end
+
     @status   = Status.find_by(uri: object_uri, account: @account)
     @status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?
 
-    delete_later!(object_uri)
-
     return if @status.nil?
 
     if @status.public_visibility? || @status.unlisted_visibility?
@@ -64,4 +71,17 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
   def payload
     @payload ||= Oj.dump(@json)
   end
+
+  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 36d3c57300c945f51b3da6a7cb48d721e37dab9d..0d10d6c3c93557fcab03cf387975c346eae4a750 100644
--- a/app/lib/activitypub/activity/flag.rb
+++ b/app/lib/activitypub/activity/flag.rb
@@ -2,12 +2,12 @@
 
 class ActivityPub::Activity::Flag < ActivityPub::Activity
   def perform
+    return if skip_reports?
+
     target_accounts            = object_uris.map { |uri| account_from_uri(uri) }.compact.select(&:local?)
     target_statuses_by_account = object_uris.map { |uri| status_from_uri(uri) }.compact.select(&:local?).group_by(&:account_id)
 
     target_accounts.each do |target_account|
-      next if Report.where(account: @account, target_account: target_account).exists?
-
       target_statuses = target_statuses_by_account[target_account.id]
 
       ReportService.new.call(
@@ -19,6 +19,12 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
     end
   end
 
+  private
+
+  def skip_reports?
+    DomainBlock.find_by(domain: @account.domain)&.reject_reports?
+  end
+
   def object_uris
     @object_uris ||= Array(@object.is_a?(Array) ? @object.map { |item| value_or_id(item) } : value_or_id(@object))
   end
diff --git a/app/lib/activitypub/activity/follow.rb b/app/lib/activitypub/activity/follow.rb
index 826dcf18ef27d76f3ff71304f04fff4c3db17259..1e805c0d1758fa4349ff89de051b2cc3f66a0afe 100644
--- a/app/lib/activitypub/activity/follow.rb
+++ b/app/lib/activitypub/activity/follow.rb
@@ -6,14 +6,14 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
 
     return if target_account.nil? || !target_account.local? || delete_arrived_first?(@json['id']) || @account.requested?(target_account)
 
-    if target_account.blocking?(@account) || target_account.domain_blocking?(@account.domain)
+    if target_account.blocking?(@account) || target_account.domain_blocking?(@account.domain) || target_account.moved?
       reject_follow_request!(target_account)
       return
     end
 
     # Fast-forward repeat follow requests
     if @account.following?(target_account)
-      AuthorizeFollowService.new.call(@account, target_account, skip_follow_request: true)
+      AuthorizeFollowService.new.call(@account, target_account, skip_follow_request: true, follow_request_uri: @json['id'])
       return
     end
 
@@ -28,7 +28,7 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
   end
 
   def reject_follow_request!(target_account)
-    json = Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(FollowRequest.new(account: @account, target_account: target_account, uri: @json['id']), serializer: ActivityPub::RejectFollowSerializer, adapter: ActivityPub::Adapter).as_json).sign!(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
     ActivityPub::DeliveryWorker.perform_async(json, target_account.id, @account.inbox_url)
   end
 end
diff --git a/app/lib/activitypub/activity/move.rb b/app/lib/activitypub/activity/move.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d7a5f595cc1c6707ce247fb6f5dafa1a924f6dd6
--- /dev/null
+++ b/app/lib/activitypub/activity/move.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+class ActivityPub::Activity::Move < ActivityPub::Activity
+  PROCESSING_COOLDOWN = 7.days.seconds
+
+  def perform
+    return if origin_account.uri != object_uri || processed?
+
+    mark_as_processing!
+
+    target_account = ActivityPub::FetchRemoteAccountService.new.call(target_uri)
+
+    return if target_account.nil? || !target_account.also_known_as.include?(origin_account.uri)
+
+    # In case for some reason we didn't have a redirect for the profile already, set it
+    origin_account.update(moved_to_account: target_account) if origin_account.moved_to_account_id.nil?
+
+    # Initiate a re-follow for each follower
+    origin_account.followers.local.select(:id).find_in_batches do |follower_accounts|
+      UnfollowFollowWorker.push_bulk(follower_accounts.map(&:id)) do |follower_account_id|
+        [follower_account_id, origin_account.id, target_account.id]
+      end
+    end
+  end
+
+  private
+
+  def origin_account
+    @account
+  end
+
+  def target_uri
+    value_or_id(@json['target'])
+  end
+
+  def processed?
+    redis.exists("move_in_progress:#{@account.id}")
+  end
+
+  def mark_as_processing!
+    redis.setex("move_in_progress:#{@account.id}", PROCESSING_COOLDOWN, true)
+  end
+end
diff --git a/app/lib/activitypub/activity/reject.rb b/app/lib/activitypub/activity/reject.rb
index 28d472883f2748be37385033f1106e9d4c6ea79c..dba21fb9a7d896c23a7a385f935b72f34fb31b40 100644
--- a/app/lib/activitypub/activity/reject.rb
+++ b/app/lib/activitypub/activity/reject.rb
@@ -11,6 +11,8 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
   private
 
   def reject_follow
+    return reject_follow_for_relay if relay_follow?
+
     target_account = account_from_uri(target_uri)
 
     return if target_account.nil? || !target_account.local?
@@ -21,6 +23,18 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
     UnfollowService.new.call(target_account, @account) if target_account.following?(@account)
   end
 
+  def reject_follow_for_relay
+    relay.update!(state: :rejected)
+  end
+
+  def relay
+    @relay ||= Relay.find_by(follow_activity_id: object_uri) unless object_uri.nil?
+  end
+
+  def relay_follow?
+    relay.present?
+  end
+
   def target_uri
     @target_uri ||= value_or_id(@object['actor'])
   end
diff --git a/app/lib/activitypub/activity/undo.rb b/app/lib/activitypub/activity/undo.rb
index cbed417c4e850ec97ab7b5c07fea2d166d297e00..599823c6e25db8ffac3ed5c1a513e92ef40bf7a8 100644
--- a/app/lib/activitypub/activity/undo.rb
+++ b/app/lib/activitypub/activity/undo.rb
@@ -5,6 +5,8 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
     case @object['type']
     when 'Announce'
       undo_announce
+    when 'Accept'
+      undo_accept
     when 'Follow'
       undo_follow
     when 'Like'
@@ -17,6 +19,8 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
   private
 
   def undo_announce
+    return if object_uri.nil?
+
     status   = Status.find_by(uri: object_uri, account: @account)
     status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?
 
@@ -27,6 +31,10 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
     end
   end
 
+  def undo_accept
+    ::Follow.find_by(target_account: @account, uri: target_uri)&.revoke_request!
+  end
+
   def undo_follow
     target_account = account_from_uri(target_uri)
 
diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb
index aa5907f033d5951fdee091af9137a28c3f8dc25e..67dae3f81388a87c6ebfee0d54c6a4334ecfaa21 100644
--- a/app/lib/activitypub/activity/update.rb
+++ b/app/lib/activitypub/activity/update.rb
@@ -11,6 +11,7 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
 
   def update_account
     return if @account.uri != object_uri
-    ActivityPub::ProcessAccountService.new.call(@account.username, @account.domain, @object)
+
+    ActivityPub::ProcessAccountService.new.call(@account.username, @account.domain, @object, signed_with_known_key: true)
   end
 end
diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb
index e880499f1a621284784c0434dd81536ce43b74c9..99f4d93055403d39b8ebfb7e1b9d7eea861c08e5 100644
--- a/app/lib/activitypub/adapter.rb
+++ b/app/lib/activitypub/adapter.rb
@@ -9,7 +9,8 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
       {
         'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
         'sensitive'                 => 'as:sensitive',
-        'movedTo'                   => 'as:movedTo',
+        'movedTo'                   => { '@id' => 'as:movedTo', '@type' => '@id' },
+        'alsoKnownAs'               => { '@id' => 'as:alsoKnownAs', '@type' => '@id' },
         'Hashtag'                   => 'as:Hashtag',
         'ostatus'                   => 'http://ostatus.org#',
         'atomUri'                   => 'ostatus:atomUri',
@@ -18,7 +19,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
         'toot'                      => 'http://joinmastodon.org/ns#',
         'Emoji'                     => 'toot:Emoji',
         'focalPoint'                => { '@container' => '@list', '@id' => 'toot:focalPoint' },
-        'featured'                  => 'toot:featured',
+        'featured'                  => { '@id' => 'toot:featured', '@type' => '@id' },
         'schema'                    => 'http://schema.org#',
         'PropertyValue'             => 'schema:PropertyValue',
         'value'                     => 'schema:value',
diff --git a/app/lib/activitypub/linked_data_signature.rb b/app/lib/activitypub/linked_data_signature.rb
index 16142a6ff474811c9ee62508f4c62df725fb6e42..f52a8f406fde3dfd07d7830fe32c929418222346 100644
--- a/app/lib/activitypub/linked_data_signature.rb
+++ b/app/lib/activitypub/linked_data_signature.rb
@@ -32,7 +32,7 @@ class ActivityPub::LinkedDataSignature
     end
   end
 
-  def sign!(creator)
+  def sign!(creator, sign_with: nil)
     options = {
       'type'    => 'RsaSignature2017',
       'creator' => [ActivityPub::TagManager.instance.uri_for(creator), '#main-key'].join,
@@ -42,8 +42,9 @@ class ActivityPub::LinkedDataSignature
     options_hash  = hash(options.without('type', 'id', 'signatureValue').merge('@context' => CONTEXT))
     document_hash = hash(@json.without('signature'))
     to_be_signed  = options_hash + document_hash
+    keypair       = sign_with.present? ? OpenSSL::PKey::RSA.new(sign_with) : creator.keypair
 
-    signature = Base64.strict_encode64(creator.keypair.sign(OpenSSL::Digest::SHA256.new, to_be_signed))
+    signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest::SHA256.new, to_be_signed))
 
     @json.merge('signature' => options.merge('signatureValue' => signature))
   end
diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb
index 95d1cf9f35326d7ea64016fcdce55b1a1e784d26..be3a562d00cdf46ec9b758f42389016673cddcc7 100644
--- a/app/lib/activitypub/tag_manager.rb
+++ b/app/lib/activitypub/tag_manager.rb
@@ -58,8 +58,8 @@ class ActivityPub::TagManager
       [COLLECTIONS[:public]]
     when 'unlisted', 'private'
       [account_followers_url(status.account)]
-    when 'direct'
-      status.mentions.map { |mention| uri_for(mention.account) }
+    when 'direct', 'limited'
+      status.active_mentions.map { |mention| uri_for(mention.account) }
     end
   end
 
@@ -80,7 +80,7 @@ class ActivityPub::TagManager
       cc << COLLECTIONS[:public]
     end
 
-    cc.concat(status.mentions.map { |mention| uri_for(mention.account) }) unless status.direct_visibility?
+    cc.concat(status.active_mentions.map { |mention| uri_for(mention.account) }) unless status.direct_visibility? || status.limited_visibility?
 
     cc
   end
diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb
index 2aa37389ca627eac780758a07c3813ce26cd476a..8fff544a054a35743d69b774926f0843f4af2ef0 100644
--- a/app/lib/entity_cache.rb
+++ b/app/lib/entity_cache.rb
@@ -21,7 +21,7 @@ class EntityCache
     end
 
     unless uncached_ids.empty?
-      uncached = CustomEmoji.where(shortcode: shortcodes, domain: domain, disabled: false).map { |item| [item.shortcode, item] }.to_h
+      uncached = CustomEmoji.where(shortcode: shortcodes, domain: domain, disabled: false).each_with_object({}) { |item, h| h[item.shortcode] = item }
       uncached.each_value { |item| Rails.cache.write(to_key(:emoji, item.shortcode, domain), item, expires_in: MAX_EXPIRATION) }
     end
 
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 14cba70dcf3d74df68a523200172a3e47c25a846..f99df33e54f0d2d61104a8bbc1029008eb3f5b0d 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -27,7 +27,7 @@ class FeedManager
   end
 
   def push_to_home(account, status)
-    return false unless add_to_feed(:home, account.id, status)
+    return false unless add_to_feed(:home, account.id, status, account.user&.aggregates_reblogs?)
     trim(:home, account.id)
     PushUpdateWorker.perform_async(account.id, status.id, "timeline:#{account.id}") if push_update_required?("timeline:#{account.id}")
     true
@@ -40,7 +40,12 @@ class FeedManager
   end
 
   def push_to_list(list, status)
-    return false unless add_to_feed(:list, list.id, status)
+    if status.reply? && status.in_reply_to_account_id != status.account_id
+      should_filter = status.in_reply_to_account_id != list.account_id
+      should_filter &&= !ListAccount.where(list_id: list.id, account_id: status.in_reply_to_account_id).exists?
+      return false if should_filter
+    end
+    return false unless add_to_feed(:list, list.id, status, list.account.user&.aggregates_reblogs?)
     trim(:list, list.id)
     PushUpdateWorker.perform_async(list.account_id, status.id, "timeline:list:#{list.id}") if push_update_required?("timeline:list:#{list.id}")
     true
@@ -87,8 +92,8 @@ class FeedManager
     end
 
     query.each do |status|
-      next if status.direct_visibility? || filter?(:home, status, into_account)
-      add_to_feed(:home, into_account.id, status)
+      next if status.direct_visibility? || status.limited_visibility? || filter?(:home, status, into_account)
+      add_to_feed(:home, into_account.id, status, into_account.user&.aggregates_reblogs?)
     end
 
     trim(:home, into_account.id)
@@ -126,7 +131,7 @@ class FeedManager
 
       statuses.each do |status|
         next if filter_from_home?(status, account)
-        added += 1 if add_to_feed(:home, account.id, status)
+        added += 1 if add_to_feed(:home, account.id, status, account.user&.aggregates_reblogs?)
       end
 
       break unless added.zero?
@@ -155,12 +160,12 @@ class FeedManager
     return true  if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?)
     return true  if phrase_filtered?(status, receiver_id, :home)
 
-    check_for_blocks = status.mentions.pluck(:account_id)
+    check_for_blocks = status.active_mentions.pluck(:account_id)
     check_for_blocks.concat([status.account_id])
 
     if status.reblog?
       check_for_blocks.concat([status.reblog.account_id])
-      check_for_blocks.concat(status.reblog.mentions.pluck(:account_id))
+      check_for_blocks.concat(status.reblog.active_mentions.pluck(:account_id))
     end
 
     return true if blocks_or_mutes?(receiver_id, check_for_blocks, :home)
@@ -187,7 +192,7 @@ class FeedManager
     # This filter is called from NotifyService, but already after the sender of
     # the notification has been checked for mute/block. Therefore, it's not
     # necessary to check the author of the toot for mute/block again
-    check_for_blocks = status.mentions.pluck(:account_id)
+    check_for_blocks = status.active_mentions.pluck(:account_id)
     check_for_blocks.concat([status.in_reply_to_account]) if status.reply? && !status.in_reply_to_account_id.nil?
 
     should_filter   = blocks_or_mutes?(receiver_id, check_for_blocks, :mentions)                                                         # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted)
@@ -225,11 +230,11 @@ class FeedManager
   # added, and false if it was not added to the feed. Note that this is
   # an internal helper: callers must call trim or push updates if
   # either action is appropriate.
-  def add_to_feed(timeline_type, account_id, status)
+  def add_to_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)
       # If the original status or a reblog of it is within
       # REBLOG_FALLOFF statuses from the top, do not re-insert it into
       # the feed
@@ -288,7 +293,7 @@ class FeedManager
       # remains in the set. We could pick a random element, but this
       # set should generally be small, and it seems ideal to show the
       # oldest potential such reblog.
-      other_reblog = redis.smembers(reblog_set_key).map(&:to_i).sort.first
+      other_reblog = redis.smembers(reblog_set_key).map(&:to_i).min
 
       redis.zadd(timeline_key, other_reblog, other_reblog) if other_reblog
 
diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb
index e1ab05cc0bf769241b050c54a3ac96a92fcfb93b..05fd9eeb1261abeeb9bcbb1dbc046c5a385f9cfd 100644
--- a/app/lib/formatter.rb
+++ b/app/lib/formatter.rb
@@ -23,17 +23,17 @@ class Formatter
 
     unless status.local?
       html = reformat(raw_content)
-      html = encode_custom_emojis(html, status.emojis) if options[:custom_emojify]
+      html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify]
       return html.html_safe # rubocop:disable Rails/OutputSafety
     end
 
-    linkable_accounts = status.mentions.map(&:account)
+    linkable_accounts = status.active_mentions.map(&:account)
     linkable_accounts << status.account
 
     html = raw_content
     html = "RT @#{prepend_reblog} #{html}" if prepend_reblog
     html = encode_and_link_urls(html, linkable_accounts)
-    html = encode_custom_emojis(html, status.emojis) if options[:custom_emojify]
+    html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify]
     html = simple_format(html, {}, sanitize: false)
     html = html.delete("\n")
 
@@ -53,7 +53,7 @@ class Formatter
 
   def simplified_format(account, **options)
     html = account.local? ? linkify(account.note) : reformat(account.note)
-    html = encode_custom_emojis(html, account.emojis) if options[:custom_emojify]
+    html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify]
     html.html_safe # rubocop:disable Rails/OutputSafety
   end
 
@@ -61,22 +61,22 @@ class Formatter
     Sanitize.fragment(html, config)
   end
 
-  def format_spoiler(status)
+  def format_spoiler(status, **options)
     html = encode(status.spoiler_text)
-    html = encode_custom_emojis(html, status.emojis)
+    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) if options[:custom_emojify]
+    html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify]
     html.html_safe # rubocop:disable Rails/OutputSafety
   end
 
   def format_field(account, str, **options)
     return reformat(str).html_safe unless account.local? # rubocop:disable Rails/OutputSafety
     html = encode_and_link_urls(str, me: true)
-    html = encode_custom_emojis(html, account.emojis) if options[:custom_emojify]
+    html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify]
     html.html_safe # rubocop:disable Rails/OutputSafety
   end
 
@@ -90,8 +90,12 @@ class Formatter
 
   private
 
+  def html_entities
+    @html_entities ||= HTMLEntities.new
+  end
+
   def encode(html)
-    HTMLEntities.new.encode(html)
+    html_entities.encode(html)
   end
 
   def encode_and_link_urls(html, accounts = nil, options = {})
@@ -120,10 +124,14 @@ class Formatter
     end
   end
 
-  def encode_custom_emojis(html, emojis)
+  def encode_custom_emojis(html, emojis, animate = false)
     return html if emojis.empty?
 
-    emoji_map = emojis.map { |e| [e.shortcode, full_asset_url(e.image.url(:static))] }.to_h
+    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
 
     i                     = -1
     tag_open_index        = nil
@@ -139,7 +147,7 @@ class Formatter
         emoji     = emoji_map[shortcode]
 
         if emoji
-          replacement = "<img draggable=\"false\" class=\"emojione\" alt=\":#{shortcode}:\" title=\":#{shortcode}:\" src=\"#{emoji}\" />"
+          replacement = "<img draggable=\"false\" class=\"emojione\" alt=\":#{encode(shortcode)}:\" title=\":#{encode(shortcode)}:\" src=\"#{encode(emoji)}\" />"
           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
@@ -208,7 +216,7 @@ class Formatter
     return link_to_account(acct) unless linkable_accounts
 
     account = linkable_accounts.find { |item| TagManager.instance.same_acct?(item.acct, acct) }
-    account ? mention_html(account) : "@#{acct}"
+    account ? mention_html(account) : "@#{encode(acct)}"
   end
 
   def link_to_account(acct)
@@ -217,7 +225,7 @@ class Formatter
     domain  = nil if TagManager.instance.local_domain?(domain)
     account = EntityCache.instance.mention(username, domain)
 
-    account ? mention_html(account) : "@#{acct}"
+    account ? mention_html(account) : "@#{encode(acct)}"
   end
 
   def link_to_hashtag(entity)
@@ -235,10 +243,10 @@ class Formatter
   end
 
   def hashtag_html(tag)
-    "<a href=\"#{tag_url(tag.downcase)}\" class=\"mention hashtag\" rel=\"tag\">#<span>#{tag}</span></a>"
+    "<a href=\"#{encode(tag_url(tag.downcase))}\" class=\"mention hashtag\" rel=\"tag\">#<span>#{encode(tag)}</span></a>"
   end
 
   def mention_html(account)
-    "<span class=\"h-card\"><a href=\"#{TagManager.instance.url_for(account)}\" class=\"u-url mention\">@<span>#{account.username}</span></a></span>"
+    "<span class=\"h-card\"><a href=\"#{encode(TagManager.instance.url_for(account))}\" class=\"u-url mention\">@<span>#{encode(account.username)}</span></a></span>"
   end
 end
diff --git a/app/lib/inline_renderer.rb b/app/lib/inline_renderer.rb
index 7cd9758ece561b114135a2c9d3c9387f77a9dd78..761a8822dfb9df720271c6803416bba2f8a6c739 100644
--- a/app/lib/inline_renderer.rb
+++ b/app/lib/inline_renderer.rb
@@ -13,6 +13,8 @@ class InlineRenderer
       serializer = REST::StatusSerializer
     when :notification
       serializer = REST::NotificationSerializer
+    when :conversation
+      serializer = REST::ConversationSerializer
     else
       return
     end
diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb
index c6f52f0c7eadb807d08f76d0010fcdb971c13601..58c8e206940ab3c3bd584be0ae84dd903fa45ffb 100644
--- a/app/lib/language_detector.rb
+++ b/app/lib/language_detector.rb
@@ -3,12 +3,17 @@
 class LanguageDetector
   include Singleton
 
+  CHARACTER_THRESHOLD = 140
+
   def initialize
     @identifier = CLD3::NNetLanguageIdentifier.new(1, 2048)
   end
 
   def detect(text, account)
-    detect_language_code(text) || default_locale(account)
+    input_text = prepare_text(text)
+    return if input_text.blank?
+
+    detect_language_code(input_text) || default_locale(account)
   end
 
   def language_names
@@ -23,8 +28,14 @@ class LanguageDetector
     simplify_text(text).strip
   end
 
+  def unreliable_input?(text)
+    text.size < CHARACTER_THRESHOLD
+  end
+
   def detect_language_code(text)
-    result = @identifier.find_language(prepare_text(text))
+    return if unreliable_input?(text)
+
+    result = @identifier.find_language(text)
     iso6391(result.language.to_s).to_sym if result.reliable?
   end
 
@@ -66,6 +77,6 @@ class LanguageDetector
   end
 
   def default_locale(account)
-    account.user_locale&.to_sym
+    return account.user_locale&.to_sym || I18n.default_locale if account.local?
   end
 end
diff --git a/app/lib/ostatus/activity/creation.rb b/app/lib/ostatus/activity/creation.rb
index d3a303a0c4896f23edeaf68db9a7ab77f622c4a0..3840c8fbfed5b6507419ca5d8d4f07ae902ad66f 100644
--- a/app/lib/ostatus/activity/creation.rb
+++ b/app/lib/ostatus/activity/creation.rb
@@ -7,7 +7,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
       return [nil, false]
     end
 
-    return [nil, false] if @account.suspended?
+    return [nil, false] if @account.suspended? || invalid_origin?
 
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
@@ -57,7 +57,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
       save_emojis(status)
     end
 
-    if thread? && status.thread.nil?
+    if thread? && status.thread.nil? && Request.valid_url?(thread.second)
       Rails.logger.debug "Trying to attach #{status.id} (#{id}) to #{thread.first}"
       ThreadResolveWorker.perform_async(status.id, thread.second)
     end
@@ -204,6 +204,15 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
     end
   end
 
+  def invalid_origin?
+    return false unless id.start_with?('http') # Legacy IDs cannot be checked
+
+    needle = Addressable::URI.parse(id).normalized_host
+
+    !(needle.casecmp(@account.domain).zero? ||
+      needle.casecmp(Addressable::URI.parse(@account.remote_url.presence || @account.uri).normalized_host).zero?)
+  end
+
   def lock_options
     { redis: Redis.current, key: "create:#{id}" }
   end
diff --git a/app/lib/ostatus/atom_serializer.rb b/app/lib/ostatus/atom_serializer.rb
index 5c6ff4f9b9fd04b5d4bf42e30b79a3de3ea9d013..7a181fb404563e0fa845b3138611b253b2b3fde4 100644
--- a/app/lib/ostatus/atom_serializer.rb
+++ b/app/lib/ostatus/atom_serializer.rb
@@ -352,9 +352,9 @@ 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).to_str || '.', type: 'html', 'xml:lang': status.language)
 
-    status.mentions.sort_by(&:id).each do |mentioned|
+    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))
     end
 
diff --git a/app/lib/potential_friendship_tracker.rb b/app/lib/potential_friendship_tracker.rb
index 362482669eb79b15af2c903f73f8d3108c01dc12..017a9748d5f979caa16712c3a2fabe4d185be702 100644
--- a/app/lib/potential_friendship_tracker.rb
+++ b/app/lib/potential_friendship_tracker.rb
@@ -12,6 +12,8 @@ class PotentialFriendshipTracker
 
   class << self
     def record(account_id, target_account_id, action)
+      return if account_id == target_account_id
+
       key    = "interactions:#{account_id}"
       weight = WEIGHTS[action]
 
diff --git a/app/lib/request.rb b/app/lib/request.rb
index 576ed23ca0c21561c81147f642523e74dba1805b..ef4aeaf29018ebfab1797f8ee33a2a37b1826e19 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -2,6 +2,17 @@
 
 require 'ipaddr'
 require 'socket'
+require 'resolv'
+
+# Monkey-patch the HTTP.rb timeout class to avoid using a timeout block
+# around the Socket#open method, since we use our own timeout blocks inside
+# that method
+class HTTP::Timeout::PerOperation
+  def connect(socket_class, host, port, nodelay = false)
+    @socket = socket_class.open(host, port)
+    @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) if nodelay
+  end
+end
 
 class Request
   REQUEST_TARGET = '(request-target)'
@@ -22,10 +33,11 @@ class Request
     set_digest! if options.key?(:body)
   end
 
-  def on_behalf_of(account, key_id_format = :acct)
+  def on_behalf_of(account, key_id_format = :acct, sign_with: nil)
     raise ArgumentError unless account.local?
 
     @account       = account
+    @keypair       = sign_with.present? ? OpenSSL::PKey::RSA.new(sign_with) : @account.keypair
     @key_id_format = key_id_format
 
     self
@@ -44,7 +56,7 @@ class Request
     end
 
     begin
-      yield response.extend(ClientLimit)
+      yield response.extend(ClientLimit) if block_given?
     ensure
       http_client.close
     end
@@ -54,6 +66,18 @@ class Request
     (@account ? @headers.merge('Signature' => signature) : @headers).without(REQUEST_TARGET)
   end
 
+  class << self
+    def valid_url?(url)
+      begin
+        parsed_url = Addressable::URI.parse(url)
+      rescue Addressable::URI::InvalidURIError
+        return false
+      end
+
+      %w(http https).include?(parsed_url.scheme) && parsed_url.host.present?
+    end
+  end
+
   private
 
   def set_common_headers!
@@ -70,17 +94,17 @@ class Request
 
   def signature
     algorithm = 'rsa-sha256'
-    signature = Base64.strict_encode64(@account.keypair.sign(OpenSSL::Digest::SHA256.new, signed_string))
+    signature = Base64.strict_encode64(@keypair.sign(OpenSSL::Digest::SHA256.new, signed_string))
 
-    "keyId=\"#{key_id}\",algorithm=\"#{algorithm}\",headers=\"#{signed_headers}\",signature=\"#{signature}\""
+    "keyId=\"#{key_id}\",algorithm=\"#{algorithm}\",headers=\"#{signed_headers.keys.join(' ').downcase}\",signature=\"#{signature}\""
   end
 
   def signed_string
-    @headers.map { |key, value| "#{key.downcase}: #{value}" }.join("\n")
+    signed_headers.map { |key, value| "#{key.downcase}: #{value}" }.join("\n")
   end
 
   def signed_headers
-    @headers.keys.join(' ').downcase
+    @headers.without('User-Agent', 'Accept-Encoding')
   end
 
   def key_id
@@ -93,7 +117,11 @@ class Request
   end
 
   def timeout
-    { write: 10, connect: 10, read: 10 }
+    # We enforce a 1s timeout on DNS resolving, 10s timeout on socket opening
+    # and 5s timeout on the TLS handshake, meaning the worst case should take
+    # about 16s in total
+
+    { connect: 5, read: 10, write: 10 }
   end
 
   def http_client
@@ -138,17 +166,34 @@ class Request
   class Socket < TCPSocket
     class << self
       def open(host, *args)
-        return super host, *args if thru_hidden_service? host
+        return super(host, *args) if thru_hidden_service?(host)
+
         outer_e = nil
-        Addrinfo.foreach(host, nil, nil, :SOCK_STREAM) do |address|
-          begin
-            raise Mastodon::HostValidationError if PrivateAddressCheck.private_address? IPAddr.new(address.ip_address)
-            return super address.ip_address, *args
-          rescue => e
-            outer_e = e
+
+        Resolv::DNS.open do |dns|
+          dns.timeouts = 1
+
+          addresses = dns.getaddresses(host).take(2)
+          time_slot = 10.0 / addresses.size
+
+          addresses.each do |address|
+            begin
+              raise Mastodon::HostValidationError if PrivateAddressCheck.private_address?(IPAddr.new(address.to_s))
+
+              ::Timeout.timeout(time_slot, HTTP::TimeoutError) do
+                return super(address.to_s, *args)
+              end
+            rescue => e
+              outer_e = e
+            end
           end
         end
-        raise outer_e if outer_e
+
+        if outer_e
+          raise outer_e
+        else
+          raise SocketError, "No address for #{host}"
+        end
       end
 
       alias new open
diff --git a/app/lib/sanitize_config.rb b/app/lib/sanitize_config.rb
index c2b4669245af232242ad3cc8fda1b21952adf151..1bba4a5a6eb3c90379699d705b3b76e584134f0b 100644
--- a/app/lib/sanitize_config.rb
+++ b/app/lib/sanitize_config.rb
@@ -2,7 +2,7 @@
 
 class Sanitize
   module Config
-    HTTP_PROTOCOLS ||= ['http', 'https', :relative].freeze
+    HTTP_PROTOCOLS ||= ['http', 'https', 'dat', 'dweb', 'ipfs', 'ipns', 'ssb', 'gopher', :relative].freeze
 
     CLASS_WHITELIST_TRANSFORMER = lambda do |env|
       node = env[:node]
diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb
index de4af3009751956a95398d6948ca63c52a17c439..3653ab1149d5432c53cb709f0b6e3ba4e5e022c9 100644
--- a/app/lib/settings/scoped_settings.rb
+++ b/app/lib/settings/scoped_settings.rb
@@ -2,6 +2,10 @@
 
 module Settings
   class ScopedSettings
+    DEFAULTING_TO_UNSCOPED = %w(
+      theme
+    ).freeze
+
     def initialize(object)
       @object = object
     end
@@ -27,7 +31,7 @@ module Settings
 
     def all_as_records
       vars = thing_scoped
-      records = vars.map { |r| [r.var, r] }.to_h
+      records = vars.each_with_object({}) { |r, h| h[r.var] = r }
 
       Setting.default_settings.each do |key, default_value|
         next if records.key?(key) || default_value.is_a?(Hash)
@@ -50,15 +54,22 @@ module Settings
       Rails.cache.fetch(Setting.cache_key(key, @object)) do
         db_val = thing_scoped.find_by(var: key.to_s)
         if db_val
-          default_value = Setting.default_settings[key]
+          default_value = ScopedSettings.default_settings[key]
           return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash)
           db_val.value
         else
-          Setting.default_settings[key]
+          ScopedSettings.default_settings[key]
         end
       end
     end
 
+    class << self
+      def default_settings
+        defaulting = DEFAULTING_TO_UNSCOPED.each_with_object({}) { |k, h| h[k] = Setting[k] }
+        Setting.default_settings.merge!(defaulting)
+      end
+    end
+
     protected
 
     def thing_scoped
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 8339593978be0d5fec757e5b8a28f39db20f840b..19b8544103ed99836e870160a735f4bc18f7a0ba 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -15,21 +15,23 @@ class UserSettingsDecorator
   private
 
   def process_update
-    user.settings['notification_emails']     = merged_notification_emails if change?('notification_emails')
-    user.settings['interactions']            = merged_interactions if change?('interactions')
-    user.settings['default_privacy']         = default_privacy_preference if change?('setting_default_privacy')
-    user.settings['default_sensitive']       = default_sensitive_preference if change?('setting_default_sensitive')
-    user.settings['default_language']        = default_language_preference if change?('setting_default_language')
-    user.settings['unfollow_modal']          = unfollow_modal_preference if change?('setting_unfollow_modal')
-    user.settings['boost_modal']             = boost_modal_preference if change?('setting_boost_modal')
-    user.settings['delete_modal']            = delete_modal_preference if change?('setting_delete_modal')
-    user.settings['auto_play_gif']           = auto_play_gif_preference if change?('setting_auto_play_gif')
-    user.settings['display_sensitive_media'] = display_sensitive_media_preference if change?('setting_display_sensitive_media')
-    user.settings['reduce_motion']           = reduce_motion_preference if change?('setting_reduce_motion')
-    user.settings['system_font_ui']          = system_font_ui_preference if change?('setting_system_font_ui')
-    user.settings['noindex']                 = noindex_preference if change?('setting_noindex')
-    user.settings['theme']                   = theme_preference if change?('setting_theme')
-    user.settings['hide_network']            = hide_network_preference if change?('setting_hide_network')
+    user.settings['notification_emails'] = merged_notification_emails if change?('notification_emails')
+    user.settings['interactions']        = merged_interactions if change?('interactions')
+    user.settings['default_privacy']     = default_privacy_preference if change?('setting_default_privacy')
+    user.settings['default_sensitive']   = default_sensitive_preference if change?('setting_default_sensitive')
+    user.settings['default_language']    = default_language_preference if change?('setting_default_language')
+    user.settings['unfollow_modal']      = unfollow_modal_preference if change?('setting_unfollow_modal')
+    user.settings['boost_modal']         = boost_modal_preference if change?('setting_boost_modal')
+    user.settings['delete_modal']        = delete_modal_preference if change?('setting_delete_modal')
+    user.settings['auto_play_gif']       = auto_play_gif_preference if change?('setting_auto_play_gif')
+    user.settings['display_media']       = display_media_preference if change?('setting_display_media')
+    user.settings['expand_spoilers']     = expand_spoilers_preference if change?('setting_expand_spoilers')
+    user.settings['reduce_motion']       = reduce_motion_preference if change?('setting_reduce_motion')
+    user.settings['system_font_ui']      = system_font_ui_preference if change?('setting_system_font_ui')
+    user.settings['noindex']             = noindex_preference if change?('setting_noindex')
+    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')
   end
 
   def merged_notification_emails
@@ -68,8 +70,12 @@ class UserSettingsDecorator
     boolean_cast_setting 'setting_auto_play_gif'
   end
 
-  def display_sensitive_media_preference
-    boolean_cast_setting 'setting_display_sensitive_media'
+  def display_media_preference
+    settings['setting_display_media']
+  end
+
+  def expand_spoilers_preference
+    boolean_cast_setting 'setting_expand_spoilers'
   end
 
   def reduce_motion_preference
@@ -92,6 +98,10 @@ class UserSettingsDecorator
     settings['setting_default_language']
   end
 
+  def aggregate_reblogs_preference
+    boolean_cast_setting 'setting_aggregate_reblogs'
+  end
+
   def boolean_cast_setting(key)
     ActiveModel::Type::Boolean.new.cast(settings[key])
   end
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index bf161b9be040d542b0e4974985d6c60513a64b60..cc585c3b76a8ee2f227cad67b34583e3a9cb8373 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -5,7 +5,6 @@ class ApplicationMailer < ActionMailer::Base
 
   helper :application
   helper :instance
-  helper :mailer
 
   protected
 
diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb
index b4584429628ce2eab5d806b2a7205663a4e9f625..66fa337c1f277a6c276fbee0e92cfc44c1c16998 100644
--- a/app/mailers/notification_mailer.rb
+++ b/app/mailers/notification_mailer.rb
@@ -66,16 +66,20 @@ class NotificationMailer < ApplicationMailer
   end
 
   def digest(recipient, **opts)
-    @me            = recipient
-    @since         = opts[:since] || @me.user.last_emailed_at || @me.user.current_sign_in_at
-    @notifications = Notification.where(account: @me, activity_type: 'Mention').where('created_at > ?', @since)
-    @follows_since = Notification.where(account: @me, activity_type: 'Follow').where('created_at > ?', @since).count
+    return if recipient.user.disabled?
+
+    @me                  = recipient
+    @since               = opts[:since] || [@me.user.last_emailed_at, (@me.user.current_sign_in_at + 1.day)].compact.max
+    @notifications_count = Notification.where(account: @me, activity_type: 'Mention').where('created_at > ?', @since).count
 
-    return if @me.user.disabled? || @notifications.empty?
+    return if @notifications_count.zero?
+
+    @notifications = Notification.where(account: @me, activity_type: 'Mention').where('created_at > ?', @since).limit(40)
+    @follows_since = Notification.where(account: @me, activity_type: 'Follow').where('created_at > ?', @since).count
 
     locale_for_account(@me) do
       mail to: @me.user.email,
-           subject: I18n.t(:subject, scope: [:notification_mailer, :digest], count: @notifications.size)
+           subject: I18n.t(:subject, scope: [:notification_mailer, :digest], count: @notifications_count)
     end
   end
 
diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb
index 9848c34a25e84ba46a631b006c8dc042b33ffc25..8f3a4ab3aa269f32857fe58ffa8bfd881a2aa945 100644
--- a/app/mailers/user_mailer.rb
+++ b/app/mailers/user_mailer.rb
@@ -16,7 +16,7 @@ class UserMailer < Devise::Mailer
     return if @resource.disabled?
 
     I18n.with_locale(@resource.locale || I18n.default_locale) do
-      mail to: @resource.unconfirmed_email.blank? ? @resource.email : @resource.unconfirmed_email,
+      mail to: @resource.unconfirmed_email.presence || @resource.email,
            subject: I18n.t(@resource.pending_reconfirmation? ? 'devise.mailer.reconfirmation_instructions.subject' : 'devise.mailer.confirmation_instructions.subject', instance: @instance),
            template_name: @resource.pending_reconfirmation? ? 'reconfirmation_instructions' : 'confirmation_instructions'
     end
@@ -78,4 +78,16 @@ class UserMailer < Devise::Mailer
       mail to: @resource.email, subject: I18n.t('user_mailer.backup_ready.subject')
     end
   end
+
+  def warning(user, warning)
+    @resource = user
+    @warning  = warning
+    @instance = Rails.configuration.x.local_domain
+
+    I18n.with_locale(@resource.locale || I18n.default_locale) do
+      mail to: @resource.email,
+           subject: I18n.t("user_mailer.warning.subject.#{@warning.action}", acct: "@#{user.account.local_username_and_domain}"),
+           reply_to: Setting.site_contact_email
+    end
+  end
 end
diff --git a/app/models/account.rb b/app/models/account.rb
index 51b3c2c7ab110c4a833b8316a3147b43c07d3dd9..963c8b8449c7837690579423c2bff8fe0c244a00 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -32,9 +32,6 @@
 #  suspended               :boolean          default(FALSE), not null
 #  locked                  :boolean          default(FALSE), not null
 #  header_remote_url       :string           default(""), not null
-#  statuses_count          :integer          default(0), not null
-#  followers_count         :integer          default(0), not null
-#  following_count         :integer          default(0), not null
 #  last_webfingered_at     :datetime
 #  inbox_url               :string           default(""), not null
 #  outbox_url              :string           default(""), not null
@@ -46,88 +43,61 @@
 #  featured_collection_url :string
 #  fields                  :jsonb
 #  actor_type              :string
+#  discoverable            :boolean
+#  also_known_as           :string           is an Array
 #
 
 class Account < ApplicationRecord
-  USERNAME_RE = /[a-z0-9_]+([a-z0-9_\.]+[a-z0-9_]+)?/i
+  USERNAME_RE = /[a-z0-9_]+([a-z0-9_\.-]+[a-z0-9_]+)?/i
   MENTION_RE  = /(?<=^|[^\/[:word:]])@((#{USERNAME_RE})(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
+  MIN_FOLLOWERS_DISCOVERY = 10
 
+  include AccountAssociations
   include AccountAvatar
   include AccountFinderConcern
   include AccountHeader
   include AccountInteractions
   include Attachmentable
   include Paginable
+  include AccountCounters
+  include DomainNormalizable
 
   enum protocol: [:ostatus, :activitypub]
 
-  # Local users
-  has_one :user, inverse_of: :account
-
   validates :username, presence: true
 
   # Remote user validations
   validates :username, uniqueness: { scope: :domain, case_sensitive: true }, if: -> { !local? && will_save_change_to_username? }
+  validates :username, format: { with: /\A#{USERNAME_RE}\z/i }, if: -> { !local? && will_save_change_to_username? }
 
   # Local user validations
   validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? }
   validates_with UniqueUsernameValidator, if: -> { local? && will_save_change_to_username? }
   validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
   validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? }
-  validates :note, length: { maximum: 65535 }, if: -> { local? && will_save_change_to_note? }
+  validates :note, note_length: { maximum: 65535 }, if: -> { local? && will_save_change_to_note? }
   validates :fields, length: { maximum: 4 }, if: -> { local? && will_save_change_to_fields? }
 
-  # Timelines
-  has_many :stream_entries, inverse_of: :account, dependent: :destroy
-  has_many :statuses, inverse_of: :account, dependent: :destroy
-  has_many :favourites, inverse_of: :account, dependent: :destroy
-  has_many :mentions, inverse_of: :account, dependent: :destroy
-  has_many :notifications, inverse_of: :account, dependent: :destroy
-
-  # Pinned statuses
-  has_many :status_pins, inverse_of: :account, dependent: :destroy
-  has_many :pinned_statuses, -> { reorder('status_pins.created_at DESC') }, through: :status_pins, class_name: 'Status', source: :status
-
-  # Media
-  has_many :media_attachments, dependent: :destroy
-
-  # PuSH subscriptions
-  has_many :subscriptions, dependent: :destroy
-
-  # Report relationships
-  has_many :reports
-  has_many :targeted_reports, class_name: 'Report', foreign_key: :target_account_id
-
-  has_many :report_notes, dependent: :destroy
-  has_many :custom_filters, inverse_of: :account, dependent: :destroy
-
-  # Moderation notes
-  has_many :account_moderation_notes, dependent: :destroy
-  has_many :targeted_moderation_notes, class_name: 'AccountModerationNote', foreign_key: :target_account_id, dependent: :destroy
-
-  # Lists
-  has_many :list_accounts, inverse_of: :account, dependent: :destroy
-  has_many :lists, through: :list_accounts
-
-  # Account migrations
-  belongs_to :moved_to_account, class_name: 'Account', optional: true
-
   scope :remote, -> { where.not(domain: nil) }
   scope :local, -> { where(domain: nil) }
-  scope :without_followers, -> { where(followers_count: 0) }
-  scope :with_followers, -> { where('followers_count > 0') }
   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 :recent, -> { reorder(id: :desc) }
+  scope :bots, -> { where(actor_type: %w(Application Service)) }
   scope :alphabetic, -> { order(domain: :asc, username: :asc) }
   scope :by_domain_accounts, -> { group(:domain).select(:domain, 'COUNT(*) AS accounts_count').order('accounts_count desc') }
   scope :matches_username, ->(value) { where(arel_table[:username].matches("#{value}%")) }
   scope :matches_display_name, ->(value) { where(arel_table[:display_name].matches("#{value}%")) }
   scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
-  scope :searchable, -> { where(suspended: false).where(moved_to_account_id: nil) }
+  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 :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') }
 
   delegate :email,
            :unconfirmed_email,
@@ -171,6 +141,10 @@ class Account < ApplicationRecord
     "#{username}@#{Rails.configuration.x.local_domain}"
   end
 
+  def local_followers_count
+    Follow.where(target_account_id: id).count
+  end
+
   def to_webfinger_s
     "acct:#{local_username_and_domain}"
   end
@@ -188,6 +162,21 @@ class Account < ApplicationRecord
     ResolveAccountService.new.call(acct)
   end
 
+  def silence!
+    update!(silenced: true)
+  end
+
+  def unsilence!
+    update!(silenced: false)
+  end
+
+  def suspend!
+    transaction do
+      user&.disable! if local?
+      update!(suspended: true)
+    end
+  end
+
   def unsuspend!
     transaction do
       user&.enable! if local?
@@ -206,16 +195,62 @@ class Account < ApplicationRecord
     @keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
   end
 
+  def tags_as_strings=(tag_names)
+    tag_names.map! { |name| name.mb_chars.downcase.to_s }
+    tag_names.uniq!
+
+    # Existing hashtags
+    hashtags_map = Tag.where(name: tag_names).each_with_object({}) { |tag, h| h[tag.name] = tag }
+
+    # Initialize not yet existing hashtags
+    tag_names.each do |name|
+      next if hashtags_map.key?(name)
+      hashtags_map[name] = Tag.new(name: name)
+    end
+
+    # Remove hashtags that are to be deleted
+    tags.each do |tag|
+      if hashtags_map.key?(tag.name)
+        hashtags_map.delete(tag.name)
+      else
+        transaction do
+          tags.delete(tag)
+          tag.decrement_count!(:accounts_count)
+        end
+      end
+    end
+
+    # Add hashtags that were so far missing
+    hashtags_map.each_value do |tag|
+      transaction do
+        tags << tag
+        tag.increment_count!(:accounts_count)
+      end
+    end
+  end
+
+  def also_known_as
+    self[:also_known_as] || []
+  end
+
   def fields
     (self[:fields] || []).map { |f| Field.new(self, f) }
   end
 
   def fields_attributes=(attributes)
-    fields = []
+    fields     = []
+    old_fields = self[:fields] || []
 
     if attributes.is_a?(Hash)
       attributes.each_value do |attr|
         next if attr[:name].blank?
+
+        previous = old_fields.find { |item| item['value'] == attr[:value] }
+
+        if previous && previous['verified_at'].present?
+          attr[:verified_at] = previous['verified_at']
+        end
+
         fields << attr
       end
     end
@@ -223,13 +258,18 @@ class Account < ApplicationRecord
     self[:fields] = fields
   end
 
+  DEFAULT_FIELDS_SIZE = 4
+
   def build_fields
-    return if fields.size >= 4
+    return if fields.size >= DEFAULT_FIELDS_SIZE
+
+    tmp = self[:fields] || []
 
-    raw_fields = self[:fields] || []
-    add_fields = 4 - raw_fields.size
-    add_fields.times { raw_fields << { name: '', value: '' } }
-    self.fields = raw_fields
+    (DEFAULT_FIELDS_SIZE - tmp.size).times do
+      tmp << { name: '', value: '' }
+    end
+
+    self.fields = tmp
   end
 
   def magic_key
@@ -282,17 +322,52 @@ class Account < ApplicationRecord
   end
 
   class Field < ActiveModelSerializers::Model
-    attributes :name, :value, :account, :errors
+    attributes :name, :value, :verified_at, :account, :errors
+
+    def initialize(account, attributes)
+      @account     = account
+      @attributes  = attributes
+      @name        = attributes['name'].strip[0, string_limit]
+      @value       = attributes['value'].strip[0, string_limit]
+      @verified_at = attributes['verified_at']&.to_datetime
+      @errors      = {}
+    end
+
+    def verified?
+      verified_at.present?
+    end
+
+    def value_for_verification
+      @value_for_verification ||= begin
+        if account.local?
+          value
+        else
+          ActionController::Base.helpers.strip_tags(value)
+        end
+      end
+    end
 
-    def initialize(account, attr)
-      @account = account
-      @name    = attr['name'].strip[0, 255]
-      @value   = attr['value'].strip[0, 255]
-      @errors  = {}
+    def verifiable?
+      value_for_verification.present? && value_for_verification.start_with?('http://', 'https://')
+    end
+
+    def mark_verified!
+      @verified_at = Time.now.utc
+      @attributes['verified_at'] = @verified_at
     end
 
     def to_h
-      { name: @name, value: @value }
+      { name: @name, value: @value, verified_at: @verified_at }
+    end
+
+    private
+
+    def string_limit
+      if account.local?
+        255
+      else
+        2047
+      end
     end
   end
 
@@ -325,7 +400,9 @@ class Account < ApplicationRecord
         LIMIT ?
       SQL
 
-      find_by_sql([sql, limit])
+      records = find_by_sql([sql, limit])
+      ActiveRecord::Associations::Preloader.new.preload(records, :account_stat)
+      records
     end
 
     def advanced_search_for(terms, account, limit = 10, following = false)
@@ -352,7 +429,7 @@ class Account < ApplicationRecord
           LIMIT ?
         SQL
 
-        find_by_sql([sql, account.id, account.id, account.id, limit])
+        records = find_by_sql([sql, account.id, account.id, account.id, limit])
       else
         sql = <<-SQL.squish
           SELECT
@@ -368,8 +445,11 @@ class Account < ApplicationRecord
           LIMIT ?
         SQL
 
-        find_by_sql([sql, account.id, account.id, limit])
+        records = find_by_sql([sql, account.id, account.id, limit])
       end
+
+      ActiveRecord::Associations::Preloader.new.preload(records, :account_stat)
+      records
     end
 
     private
@@ -388,8 +468,8 @@ class Account < ApplicationRecord
   end
 
   before_create :generate_keys
-  before_validation :normalize_domain
   before_validation :prepare_contents, if: :local?
+  before_destroy :clean_feed_manager
 
   private
 
@@ -409,10 +489,25 @@ class Account < ApplicationRecord
   def normalize_domain
     return if local?
 
-    self.domain = TagManager.instance.normalize_domain(domain)
+    super
   end
 
   def emojifiable_text
     [note, display_name, fields.map(&:value)].join(' ')
   end
+
+  def clean_feed_manager
+    reblog_key       = FeedManager.instance.key(:home, id, 'reblogs')
+    reblogged_id_set = Redis.current.zrange(reblog_key, 0, -1)
+
+    Redis.current.pipelined do
+      Redis.current.del(FeedManager.instance.key(:home, id))
+      Redis.current.del(reblog_key)
+
+      reblogged_id_set.each do |reblogged_id|
+        reblog_set_key = FeedManager.instance.key(:home, id, "reblogs:#{reblogged_id}")
+        Redis.current.del(reblog_set_key)
+      end
+    end
+  end
 end
diff --git a/app/models/account_conversation.rb b/app/models/account_conversation.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cc6b39279866bceb1c01a7d8e25d2fb394bdd146
--- /dev/null
+++ b/app/models/account_conversation.rb
@@ -0,0 +1,116 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: account_conversations
+#
+#  id                      :bigint(8)        not null, primary key
+#  account_id              :bigint(8)
+#  conversation_id         :bigint(8)
+#  participant_account_ids :bigint(8)        default([]), not null, is an Array
+#  status_ids              :bigint(8)        default([]), not null, is an Array
+#  last_status_id          :bigint(8)
+#  lock_version            :integer          default(0), not null
+#  unread                  :boolean          default(FALSE), not null
+#
+
+class AccountConversation < ApplicationRecord
+  after_commit :push_to_streaming_api
+
+  belongs_to :account
+  belongs_to :conversation
+  belongs_to :last_status, class_name: 'Status'
+
+  before_validation :set_last_status
+
+  def participant_account_ids=(arr)
+    self[:participant_account_ids] = arr.sort
+  end
+
+  def participant_accounts
+    if participant_account_ids.empty?
+      [account]
+    else
+      Account.where(id: participant_account_ids)
+    end
+  end
+
+  class << self
+    def paginate_by_id(limit, options = {})
+      if options[:min_id]
+        paginate_by_min_id(limit, options[:min_id]).reverse
+      else
+        paginate_by_max_id(limit, options[:max_id], options[:since_id])
+      end
+    end
+
+    def paginate_by_min_id(limit, min_id = nil)
+      query = order(arel_table[:last_status_id].asc).limit(limit)
+      query = query.where(arel_table[:last_status_id].gt(min_id)) if min_id.present?
+      query
+    end
+
+    def paginate_by_max_id(limit, max_id = nil, since_id = nil)
+      query = order(arel_table[:last_status_id].desc).limit(limit)
+      query = query.where(arel_table[:last_status_id].lt(max_id)) if max_id.present?
+      query = query.where(arel_table[:last_status_id].gt(since_id)) if since_id.present?
+      query
+    end
+
+    def add_status(recipient, status)
+      conversation = find_or_initialize_by(account: recipient, conversation_id: status.conversation_id, participant_account_ids: participants_from_status(recipient, status))
+
+      return conversation if conversation.status_ids.include?(status.id)
+
+      conversation.status_ids << status.id
+      conversation.unread = status.account_id != recipient.id
+      conversation.save
+      conversation
+    rescue ActiveRecord::StaleObjectError
+      retry
+    end
+
+    def remove_status(recipient, status)
+      conversation = find_by(account: recipient, conversation_id: status.conversation_id, participant_account_ids: participants_from_status(recipient, status))
+
+      return if conversation.nil?
+
+      conversation.status_ids.delete(status.id)
+
+      if conversation.status_ids.empty?
+        conversation.destroy
+      else
+        conversation.save
+      end
+
+      conversation
+    rescue ActiveRecord::StaleObjectError
+      retry
+    end
+
+    private
+
+    def participants_from_status(recipient, status)
+      ((status.active_mentions.pluck(:account_id) + [status.account_id]).uniq - [recipient.id]).sort
+    end
+  end
+
+  private
+
+  def set_last_status
+    self.status_ids     = status_ids.sort
+    self.last_status_id = status_ids.last
+  end
+
+  def push_to_streaming_api
+    return if destroyed? || !subscribed_to_timeline?
+    PushConversationWorker.perform_async(id)
+  end
+
+  def subscribed_to_timeline?
+    Redis.current.exists("subscribed:#{streaming_channel}")
+  end
+
+  def streaming_channel
+    "timeline:direct:#{account_id}"
+  end
+end
diff --git a/app/models/account_filter.rb b/app/models/account_filter.rb
index dc7a03039fe4f6ddc8de9ecea64328f4aee95382..b10f50db778b100e1aa477dcd6ac8ad01c7b4a7e 100644
--- a/app/models/account_filter.rb
+++ b/app/models/account_filter.rb
@@ -5,13 +5,14 @@ class AccountFilter
 
   def initialize(params)
     @params = params
+    set_defaults!
   end
 
   def results
-    scope = Account.alphabetic
+    scope = Account.recent.includes(:user)
 
     params.each do |key, value|
-      scope.merge!(scope_for(key, value)) if value.present?
+      scope.merge!(scope_for(key, value.to_s.strip)) if value.present?
     end
 
     scope
@@ -19,6 +20,11 @@ class AccountFilter
 
   private
 
+  def set_defaults!
+    params['local']  = '1' if params['remote'].blank?
+    params['active'] = '1' if params['suspended'].blank? && params['silenced'].blank?
+  end
+
   def scope_for(key, value)
     case key.to_s
     when 'local'
@@ -27,10 +33,10 @@ class AccountFilter
       Account.remote
     when 'by_domain'
       Account.where(domain: value)
+    when 'active'
+      Account.without_suspended
     when 'silenced'
       Account.silenced
-    when 'recent'
-      Account.recent
     when 'suspended'
       Account.suspended
     when 'username'
@@ -40,11 +46,7 @@ class AccountFilter
     when 'email'
       accounts_with_users.merge User.matches_email(value)
     when 'ip'
-      if valid_ip?(value)
-        accounts_with_users.merge User.with_recent_ip_address(value)
-      else
-        Account.default_scoped
-      end
+      valid_ip?(value) ? accounts_with_users.where('users.current_sign_in_ip <<= ?', value) : Account.none
     when 'staff'
       accounts_with_users.merge User.staff
     else
@@ -57,8 +59,7 @@ class AccountFilter
   end
 
   def valid_ip?(value)
-    IPAddr.new(value)
-    true
+    IPAddr.new(value) && true
   rescue IPAddr::InvalidAddressError
     false
   end
diff --git a/app/models/account_pin.rb b/app/models/account_pin.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b51d3d4cd4e2ae07fd31d3de2397137ed2fdd1e6
--- /dev/null
+++ b/app/models/account_pin.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: account_pins
+#
+#  id                :bigint(8)        not null, primary key
+#  account_id        :bigint(8)
+#  target_account_id :bigint(8)
+#  created_at        :datetime         not null
+#  updated_at        :datetime         not null
+#
+
+class AccountPin < ApplicationRecord
+  include Paginable
+  include RelationshipCacheable
+
+  belongs_to :account
+  belongs_to :target_account, class_name: 'Account'
+
+  validate :validate_follow_relationship
+
+  private
+
+  def validate_follow_relationship
+    errors.add(:base, I18n.t('accounts.pin_errors.following')) unless account.following?(target_account)
+  end
+end
diff --git a/app/models/account_stat.rb b/app/models/account_stat.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9813aa84ff105420b0629e5a9f501ba78296ff30
--- /dev/null
+++ b/app/models/account_stat.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: account_stats
+#
+#  id              :bigint(8)        not null, primary key
+#  account_id      :bigint(8)        not null
+#  statuses_count  :bigint(8)        default(0), not null
+#  following_count :bigint(8)        default(0), not null
+#  followers_count :bigint(8)        default(0), not null
+#  created_at      :datetime         not null
+#  updated_at      :datetime         not null
+#  last_status_at  :datetime
+#
+
+class AccountStat < ApplicationRecord
+  belongs_to :account, inverse_of: :account_stat
+
+  def increment_count!(key)
+    update(attributes_for_increment(key))
+  end
+
+  def decrement_count!(key)
+    update(key => [public_send(key) - 1, 0].max)
+  end
+
+  private
+
+  def attributes_for_increment(key)
+    attrs = { key => public_send(key) + 1 }
+    attrs[:last_status_at] = Time.now.utc if key == :statuses_count
+    attrs
+  end
+end
diff --git a/app/models/account_tag_stat.rb b/app/models/account_tag_stat.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3c36c155abede51974741ec568030d1278344158
--- /dev/null
+++ b/app/models/account_tag_stat.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: account_tag_stats
+#
+#  id             :bigint(8)        not null, primary key
+#  tag_id         :bigint(8)        not null
+#  accounts_count :bigint(8)        default(0), not null
+#  hidden         :boolean          default(FALSE), not null
+#  created_at     :datetime         not null
+#  updated_at     :datetime         not null
+#
+
+class AccountTagStat < ApplicationRecord
+  belongs_to :tag, inverse_of: :account_tag_stat
+
+  def increment_count!(key)
+    update(key => public_send(key) + 1)
+  end
+
+  def decrement_count!(key)
+    update(key => [public_send(key) - 1, 0].max)
+  end
+end
diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb
new file mode 100644
index 0000000000000000000000000000000000000000..157e6c04d1eb39d41872f3c07f1054179c6d66af
--- /dev/null
+++ b/app/models/account_warning.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: account_warnings
+#
+#  id                :bigint(8)        not null, primary key
+#  account_id        :bigint(8)
+#  target_account_id :bigint(8)
+#  action            :integer          default("none"), not null
+#  text              :text             default(""), not null
+#  created_at        :datetime         not null
+#  updated_at        :datetime         not null
+#
+
+class AccountWarning < ApplicationRecord
+  enum action: %i(none disable silence suspend), _suffix: :action
+
+  belongs_to :account, inverse_of: :account_warnings
+  belongs_to :target_account, class_name: 'Account', inverse_of: :targeted_account_warnings
+
+  scope :latest, -> { order(created_at: :desc) }
+  scope :custom, -> { where.not(text: '') }
+end
diff --git a/app/models/account_warning_preset.rb b/app/models/account_warning_preset.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ba8ceabb353da2081a7c3c747d785bfbbc57dd3c
--- /dev/null
+++ b/app/models/account_warning_preset.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: account_warning_presets
+#
+#  id         :bigint(8)        not null, primary key
+#  text       :text             default(""), not null
+#  created_at :datetime         not null
+#  updated_at :datetime         not null
+#
+
+class AccountWarningPreset < ApplicationRecord
+  validates :text, presence: true
+end
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
new file mode 100644
index 0000000000000000000000000000000000000000..84c3f880d2556efd5005cd59dea1d273f604af6f
--- /dev/null
+++ b/app/models/admin/account_action.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+class Admin::AccountAction
+  include ActiveModel::Model
+  include AccountableConcern
+  include Authorization
+
+  TYPES = %w(
+    none
+    disable
+    silence
+    suspend
+  ).freeze
+
+  attr_accessor :target_account,
+                :current_account,
+                :type,
+                :text,
+                :report_id,
+                :warning_preset_id,
+                :send_email_notification
+
+  attr_reader :warning
+
+  def save!
+    ApplicationRecord.transaction do
+      process_action!
+      process_warning!
+    end
+
+    queue_email!
+    process_reports!
+  end
+
+  def report
+    @report ||= Report.find(report_id) if report_id.present?
+  end
+
+  def with_report?
+    !report.nil?
+  end
+
+  class << self
+    def types_for_account(account)
+      if account.local?
+        TYPES
+      else
+        TYPES - %w(none disable)
+      end
+    end
+  end
+
+  private
+
+  def process_action!
+    case type
+    when 'disable'
+      handle_disable!
+    when 'silence'
+      handle_silence!
+    when 'suspend'
+      handle_suspend!
+    end
+  end
+
+  def process_warning!
+    return unless warnable?
+
+    authorize(target_account, :warn?)
+
+    @warning = AccountWarning.create!(target_account: target_account,
+                                      account: current_account,
+                                      action: type,
+                                      text: text_for_warning)
+
+    # A log entry is only interesting if the warning contains
+    # custom text from someone. Otherwise it's just noise.
+    log_action(:create, warning) if warning.text.present?
+  end
+
+  def process_reports!
+    return if report_id.blank?
+
+    authorize(report, :update?)
+
+    if type == 'none'
+      log_action(:resolve, report)
+      report.resolve!(current_account)
+    else
+      Report.where(target_account: target_account).unresolved.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
+    end
+  end
+
+  def handle_disable!
+    authorize(target_account.user, :disable?)
+    log_action(:disable, target_account.user)
+    target_account.user&.disable!
+  end
+
+  def handle_silence!
+    authorize(target_account, :silence?)
+    log_action(:silence, target_account)
+    target_account.silence!
+  end
+
+  def handle_suspend!
+    authorize(target_account, :suspend?)
+    log_action(:suspend, target_account)
+    target_account.suspend!
+    queue_suspension_worker!
+  end
+
+  def text_for_warning
+    [warning_preset&.text, text].compact.join("\n\n")
+  end
+
+  def queue_suspension_worker!
+    Admin::SuspensionWorker.perform_async(target_account.id)
+  end
+
+  def queue_email!
+    return unless warnable?
+
+    UserMailer.warning(target_account.user, warning).deliver_later!
+  end
+
+  def warnable?
+    send_email_notification && target_account.local?
+  end
+
+  def warning_preset
+    @warning_preset ||= AccountWarningPreset.find(warning_preset_id) if warning_preset_id.present?
+  end
+end
diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7dafeee34ca67cd69986c2d6cf0c402d0f469e13
--- /dev/null
+++ b/app/models/concerns/account_associations.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+module AccountAssociations
+  extend ActiveSupport::Concern
+
+  included do
+    # Local users
+    has_one :user, inverse_of: :account, dependent: :destroy
+
+    # Timelines
+    has_many :stream_entries, inverse_of: :account, dependent: :destroy
+    has_many :statuses, inverse_of: :account, dependent: :destroy
+    has_many :favourites, inverse_of: :account, dependent: :destroy
+    has_many :mentions, inverse_of: :account, dependent: :destroy
+    has_many :notifications, inverse_of: :account, dependent: :destroy
+    has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account
+    has_many :scheduled_statuses, inverse_of: :account, dependent: :destroy
+
+    # Pinned statuses
+    has_many :status_pins, inverse_of: :account, dependent: :destroy
+    has_many :pinned_statuses, -> { reorder('status_pins.created_at DESC') }, through: :status_pins, class_name: 'Status', source: :status
+
+    # Endorsements
+    has_many :account_pins, inverse_of: :account, dependent: :destroy
+    has_many :endorsed_accounts, through: :account_pins, class_name: 'Account', source: :target_account
+
+    # Media
+    has_many :media_attachments, dependent: :destroy
+
+    # PuSH subscriptions
+    has_many :subscriptions, dependent: :destroy
+
+    # Report relationships
+    has_many :reports, dependent: :destroy, inverse_of: :account
+    has_many :targeted_reports, class_name: 'Report', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
+
+    has_many :report_notes, dependent: :destroy
+    has_many :custom_filters, inverse_of: :account, dependent: :destroy
+
+    # Moderation notes
+    has_many :account_moderation_notes, dependent: :destroy, inverse_of: :account
+    has_many :targeted_moderation_notes, class_name: 'AccountModerationNote', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
+    has_many :account_warnings, dependent: :destroy, inverse_of: :account
+    has_many :targeted_account_warnings, class_name: 'AccountWarning', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
+
+    # Lists (that the account is on, not owned by the account)
+    has_many :list_accounts, inverse_of: :account, dependent: :destroy
+    has_many :lists, through: :list_accounts
+
+    # Lists (owned by the account)
+    has_many :owned_lists, class_name: 'List', dependent: :destroy, inverse_of: :account
+
+    # Account migrations
+    belongs_to :moved_to_account, class_name: 'Account', optional: true
+
+    # Hashtags
+    has_and_belongs_to_many :tags
+  end
+end
diff --git a/app/models/concerns/account_counters.rb b/app/models/concerns/account_counters.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3581df8dd8b2ac69b6806eb4b0bea7c3651eec06
--- /dev/null
+++ b/app/models/concerns/account_counters.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module AccountCounters
+  extend ActiveSupport::Concern
+
+  included do
+    has_one :account_stat, inverse_of: :account
+    after_save :save_account_stat
+  end
+
+  delegate :statuses_count,
+           :statuses_count=,
+           :following_count,
+           :following_count=,
+           :followers_count,
+           :followers_count=,
+           :increment_count!,
+           :decrement_count!,
+           :last_status_at,
+           to: :account_stat
+
+  def account_stat
+    super || build_account_stat
+  end
+
+  private
+
+  def save_account_stat
+    return unless account_stat&.changed?
+    account_stat.save
+  end
+end
diff --git a/app/models/concerns/account_finder_concern.rb b/app/models/concerns/account_finder_concern.rb
index 6b7237e89d5f32bc8d861d62e08ba07c9b77d81b..7e3bbde097799a711f6921125b629ede25e4b8d2 100644
--- a/app/models/concerns/account_finder_concern.rb
+++ b/app/models/concerns/account_finder_concern.rb
@@ -12,6 +12,10 @@ module AccountFinderConcern
       find_remote(username, domain) || raise(ActiveRecord::RecordNotFound)
     end
 
+    def representative
+      find_local(Setting.site_contact_username.gsub(/\A@/, '')) || Account.local.find_by(suspended: false)
+    end
+
     def find_local(username)
       find_remote(username, nil)
     end
diff --git a/app/models/concerns/account_header.rb b/app/models/concerns/account_header.rb
index ef40b8126b5b4b440171e1c1652d21fe89e9527c..067e166eb6ce5e340a86489c1c12d525c2c24dfd 100644
--- a/app/models/concerns/account_header.rb
+++ b/app/models/concerns/account_header.rb
@@ -5,11 +5,12 @@ module AccountHeader
 
   IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
   LIMIT = 2.megabytes
+  MAX_PIXELS = 750_000 # 1500x500px
 
   class_methods do
     def header_styles(file)
-      styles = { original: { geometry: '700x335#', file_geometry_parser: FastGeometryParser } }
-      styles[:static] = { geometry: '700x335#', format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif'
+      styles = { original: { pixels: MAX_PIXELS, file_geometry_parser: FastGeometryParser } }
+      styles[:static] = { format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif'
       styles
     end
 
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index e14e041f614afe70159baedcb738845e303f9beb..ad2909d9183aec8ba03dbc12e8589c462b08ef3d 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -40,10 +40,14 @@ module AccountInteractions
       end
     end
 
+    def endorsed_map(target_account_ids, account_id)
+      follow_mapping(AccountPin.where(account_id: account_id, target_account_id: target_account_ids), :target_account_id)
+    end
+
     def domain_blocking_map(target_account_ids, account_id)
-      accounts_map    = Account.where(id: target_account_ids).select('id, domain').map { |a| [a.id, a.domain] }.to_h
+      accounts_map    = Account.where(id: target_account_ids).select('id, domain').each_with_object({}) { |a, h| h[a.id] = a.domain }
       blocked_domains = domain_blocking_map_by_domain(accounts_map.values.compact, account_id)
-      accounts_map.map { |id, domain| [id, blocked_domains[domain]] }.to_h
+      accounts_map.reduce({}) { |h, (id, domain)| h.merge(id => blocked_domains[domain]) }
     end
 
     def domain_blocking_map_by_domain(target_domains, account_id)
@@ -190,6 +194,10 @@ module AccountInteractions
     status_pins.where(status: status).exists?
   end
 
+  def endorsed?(account)
+    account_pins.where(target_account: account).exists?
+  end
+
   def followers_for_local_distribution
     followers.local
              .joins(:user)
diff --git a/app/models/concerns/domain_normalizable.rb b/app/models/concerns/domain_normalizable.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dff3e5414f13a995236f1111f33dadbec4ef0cbb
--- /dev/null
+++ b/app/models/concerns/domain_normalizable.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module DomainNormalizable
+  extend ActiveSupport::Concern
+
+  included do
+    before_validation :normalize_domain
+  end
+
+  private
+
+  def normalize_domain
+    self.domain = TagManager.instance.normalize_domain(domain)
+  end
+end
diff --git a/app/models/concerns/expireable.rb b/app/models/concerns/expireable.rb
index 444ccdfdbe5748f244d88896edf09e63e8ed3a43..2c06314760cd34df4fff886c0c5489ca86e93aa6 100644
--- a/app/models/concerns/expireable.rb
+++ b/app/models/concerns/expireable.rb
@@ -9,7 +9,7 @@ module Expireable
     attr_reader :expires_in
 
     def expires_in=(interval)
-      self.expires_at = interval.to_i.seconds.from_now unless interval.blank?
+      self.expires_at = interval.to_i.seconds.from_now if interval.present?
       @expires_in     = interval
     end
 
diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb
index 50288e70055f484ad2be2b1cbde347197d27c36d..f263fe7af04761de25c995676342442178dda999 100644
--- a/app/models/concerns/omniauthable.rb
+++ b/app/models/concerns/omniauthable.rb
@@ -26,7 +26,7 @@ module Omniauthable
       # to prevent the identity being locked with accidentally created accounts.
       # Note that this may leave zombie accounts (with no associated identity) which
       # can be cleaned up at a later date.
-      user = signed_in_resource ? signed_in_resource : identity.user
+      user = signed_in_resource || identity.user
       user = create_for_oauth(auth) if user.nil?
 
       if identity.user.nil?
@@ -61,7 +61,7 @@ module Omniauthable
       display_name      = auth.info.full_name || [auth.info.first_name, auth.info.last_name].join(' ')
 
       {
-        email: email ? email : "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com",
+        email: email || "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com",
         password: Devise.friendly_token[0, 20],
         account_attributes: {
           username: ensure_unique_username(auth.uid),
diff --git a/app/models/concerns/paginable.rb b/app/models/concerns/paginable.rb
index 66695677e9af6990bca0382c2b76d45bc2990a45..8863094f7d467be0ac73ae1279648d9f24b4347d 100644
--- a/app/models/concerns/paginable.rb
+++ b/app/models/concerns/paginable.rb
@@ -19,5 +19,13 @@ module Paginable
       query = query.where(arel_table[:id].gt(min_id)) if min_id.present?
       query
     }
+
+    scope :paginate_by_id, ->(limit, options = {}) {
+      if options[:min_id].present?
+        paginate_by_min_id(limit, options[:min_id]).reverse
+      else
+        paginate_by_max_id(limit, options[:max_id], options[:since_id])
+      end
+    }
   end
 end
diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb
index c17f19a60050bb1a0916b4a9c041aade37692ca0..9372a963bf64eef747b062399d3e05639def5567 100644
--- a/app/models/concerns/remotable.rb
+++ b/app/models/concerns/remotable.rb
@@ -18,7 +18,7 @@ module Remotable
           return
         end
 
-        return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.empty? || self[attribute_name] == url
+        return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.blank? || self[attribute_name] == url
 
         begin
           Request.new(:get, url).perform do |response|
diff --git a/app/models/concerns/status_threading_concern.rb b/app/models/concerns/status_threading_concern.rb
index fa441469c11c80766bea1baf62313106e8ae2f01..b9c800c2aabdbb3a262dd9839ee6c6ede2f7a2a4 100644
--- a/app/models/concerns/status_threading_concern.rb
+++ b/app/models/concerns/status_threading_concern.rb
@@ -8,7 +8,7 @@ module StatusThreadingConcern
   end
 
   def descendants(limit, account = nil, max_child_id = nil, since_child_id = nil, depth = nil)
-    find_statuses_from_tree_path(descendant_ids(limit, max_child_id, since_child_id, depth), account)
+    find_statuses_from_tree_path(descendant_ids(limit, max_child_id, since_child_id, depth), account, promote: true)
   end
 
   private
@@ -76,7 +76,7 @@ module StatusThreadingConcern
     descendants_with_self - [self]
   end
 
-  def find_statuses_from_tree_path(ids, account)
+  def find_statuses_from_tree_path(ids, account, promote: false)
     statuses    = statuses_with_accounts(ids).to_a
     account_ids = statuses.map(&:account_id).uniq
     domains     = statuses.map(&:account_domain).compact.uniq
@@ -86,6 +86,28 @@ module StatusThreadingConcern
 
     # Order ancestors/descendants by tree path
     statuses.sort_by! { |status| ids.index(status.id) }
+
+    # Bring self-replies to the top
+    if promote
+      promote_by!(statuses) { |status| status.in_reply_to_account_id == status.account_id }
+    else
+      statuses
+    end
+  end
+
+  def promote_by!(arr)
+    insert_at = arr.find_index { |item| !yield(item) }
+
+    return arr if insert_at.nil?
+
+    arr.each_with_index do |item, index|
+      next if index <= insert_at || !yield(item)
+
+      arr.insert(insert_at, arr.delete_at(index))
+      insert_at += 1
+    end
+
+    arr
   end
 
   def relations_map_for_account(account, account_ids, domains)
diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb
index b99ed01f081cab2303d47d559c1a8a9b7c350958..d3cc7050492ea5523ccde7596eebcfba777d4f3c 100644
--- a/app/models/custom_emoji.rb
+++ b/app/models/custom_emoji.rb
@@ -31,6 +31,8 @@ class CustomEmoji < ApplicationRecord
 
   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 :shortcode, uniqueness: { scope: :domain }, format: { with: /\A#{SHORTCODE_RE_FRAGMENT}\z/ }, length: { minimum: 2 }
 
@@ -73,4 +75,8 @@ class CustomEmoji < ApplicationRecord
   def remove_entity_cache
     Rails.cache.delete(EntityCache.instance.to_key(:emoji, shortcode, domain))
   end
+
+  def downcase_domain
+    self.domain = domain.downcase unless domain.nil?
+  end
 end
diff --git a/app/models/custom_emoji_filter.rb b/app/models/custom_emoji_filter.rb
index c4bc310bb0773d60b5136117a6832edff6435ccb..7649055d2839037ded1cd8eef11f3244c1258a0a 100644
--- a/app/models/custom_emoji_filter.rb
+++ b/app/models/custom_emoji_filter.rb
@@ -26,7 +26,7 @@ class CustomEmojiFilter
     when 'remote'
       CustomEmoji.remote
     when 'by_domain'
-      CustomEmoji.where(domain: value)
+      CustomEmoji.where(domain: value.downcase)
     when 'shortcode'
       CustomEmoji.search(value)
     else
diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb
index 93658793bd437e98a0c5eb97f604b4f5ad94e9b9..1064ea7c8f29bbdf3763f365e644a44b0e30860d 100644
--- a/app/models/domain_block.rb
+++ b/app/models/domain_block.rb
@@ -3,15 +3,18 @@
 #
 # Table name: domain_blocks
 #
-#  id           :bigint(8)        not null, primary key
-#  domain       :string           default(""), not null
-#  created_at   :datetime         not null
-#  updated_at   :datetime         not null
-#  severity     :integer          default("silence")
-#  reject_media :boolean          default(FALSE), not null
+#  id             :bigint(8)        not null, primary key
+#  domain         :string           default(""), not null
+#  created_at     :datetime         not null
+#  updated_at     :datetime         not null
+#  severity       :integer          default("silence")
+#  reject_media   :boolean          default(FALSE), not null
+#  reject_reports :boolean          default(FALSE), not null
 #
 
 class DomainBlock < ApplicationRecord
+  include DomainNormalizable
+
   enum severity: [:silence, :suspend, :noop]
 
   attr_accessor :retroactive
@@ -24,12 +27,4 @@ class DomainBlock < ApplicationRecord
   def self.blocked?(domain)
     where(domain: domain, severity: :suspend).exists?
   end
-
-  before_validation :normalize_domain
-
-  private
-
-  def normalize_domain
-    self.domain = TagManager.instance.normalize_domain(domain)
-  end
 end
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb
index 10490375bc224cd39c42260e96332970c2f005c6..0fcd36477b927942e5e02dca35db7dcfdafe8999 100644
--- a/app/models/email_domain_block.rb
+++ b/app/models/email_domain_block.rb
@@ -10,7 +10,7 @@
 #
 
 class EmailDomainBlock < ApplicationRecord
-  before_validation :normalize_domain
+  include DomainNormalizable
 
   validates :domain, presence: true, uniqueness: true
 
@@ -27,10 +27,4 @@ class EmailDomainBlock < ApplicationRecord
 
     where(domain: domain).exists?
   end
-
-  private
-
-  def normalize_domain
-    self.domain = TagManager.instance.normalize_domain(domain)
-  end
 end
diff --git a/app/models/export.rb b/app/models/export.rb
index f0d5dd2557dd8d68959eec21fdbd221273a3ac7d..a2520e9c244f34cf0ef609be5b06a8d4e169672f 100644
--- a/app/models/export.rb
+++ b/app/models/export.rb
@@ -9,23 +9,53 @@ class Export
   end
 
   def to_blocked_accounts_csv
-    to_csv account.blocking
+    to_csv account.blocking.select(:username, :domain)
   end
 
   def to_muted_accounts_csv
-    to_csv account.muting
+    to_csv account.muting.select(:username, :domain)
   end
 
   def to_following_accounts_csv
-    to_csv account.following
+    to_csv account.following.select(:username, :domain)
+  end
+
+  def to_lists_csv
+    CSV.generate do |csv|
+      account.owned_lists.select(:title).each do |list|
+        list.accounts.select(:username, :domain).each do |account|
+          csv << [list.title, acct(account)]
+        end
+      end
+    end
+  end
+
+  def to_blocked_domains_csv
+    CSV.generate do |csv|
+      account.domain_blocks.pluck(:domain).each do |domain|
+        csv << [domain]
+      end
+    end
   end
 
   def total_storage
     account.media_attachments.sum(:file_file_size)
   end
 
+  def total_statuses
+    account.statuses_count
+  end
+
   def total_follows
-    account.following.count
+    account.following_count
+  end
+
+  def total_lists
+    account.owned_lists.count
+  end
+
+  def total_followers
+    account.followers_count
   end
 
   def total_blocks
@@ -36,13 +66,21 @@ class Export
     account.muting.count
   end
 
+  def total_domain_blocks
+    account.domain_blocks.count
+  end
+
   private
 
   def to_csv(accounts)
     CSV.generate do |csv|
       accounts.each do |account|
-        csv << [(account.local? ? account.local_username_and_domain : account.acct)]
+        csv << [acct(account)]
       end
     end
   end
+
+  def acct(account)
+    account.local? ? account.local_username_and_domain : account.acct
+  end
 end
diff --git a/app/models/favourite.rb b/app/models/favourite.rb
index 0fce82f6f92a3fe4891b110e1e213dbd52923c17..17f8c9fa631d2a758512dff8cb458ad2e92e1505 100644
--- a/app/models/favourite.rb
+++ b/app/models/favourite.rb
@@ -32,20 +32,11 @@ class Favourite < ApplicationRecord
   private
 
   def increment_cache_counters
-    if association(:status).loaded?
-      status.update_attribute(:favourites_count, status.favourites_count + 1)
-    else
-      Status.where(id: status_id).update_all('favourites_count = COALESCE(favourites_count, 0) + 1')
-    end
+    status&.increment_count!(:favourites_count)
   end
 
   def decrement_cache_counters
     return if association(:status).loaded? && (status.marked_for_destruction? || status.marked_for_mass_destruction?)
-
-    if association(:status).loaded?
-      status.update_attribute(:favourites_count, [status.favourites_count - 1, 0].max)
-    else
-      Status.where(id: status_id).update_all('favourites_count = GREATEST(COALESCE(favourites_count, 0) - 1, 0)')
-    end
+    status&.decrement_count!(:favourites_count)
   end
 end
diff --git a/app/models/feed.rb b/app/models/feed.rb
index d99f1ffb2c7620025fc0cdaf627d73ddd7a5d3d5..5bce88f25522df0a9797a30672e46195e30c2793 100644
--- a/app/models/feed.rb
+++ b/app/models/feed.rb
@@ -6,16 +6,20 @@ class Feed
     @id   = id
   end
 
-  def get(limit, max_id = nil, since_id = nil)
-    from_redis(limit, max_id, since_id)
+  def get(limit, max_id = nil, since_id = nil, min_id = nil)
+    from_redis(limit, max_id, since_id, min_id)
   end
 
   protected
 
-  def from_redis(limit, max_id, since_id)
-    max_id     = '+inf' if max_id.blank?
-    since_id   = '-inf' if since_id.blank?
-    unhydrated = redis.zrevrangebyscore(key, "(#{max_id}", "(#{since_id}", limit: [0, limit], with_scores: true).map(&:first).map(&:to_i)
+  def from_redis(limit, max_id, since_id, min_id)
+    if min_id.blank?
+      max_id     = '+inf' if max_id.blank?
+      since_id   = '-inf' if since_id.blank?
+      unhydrated = redis.zrevrangebyscore(key, "(#{max_id}", "(#{since_id}", limit: [0, limit], with_scores: true).map(&:first).map(&:to_i)
+    else
+      unhydrated = redis.zrangebyscore(key, "(#{min_id}", '+inf', limit: [0, limit], with_scores: true).map(&:first).map(&:to_i)
+    end
 
     Status.where(id: unhydrated).cache_ids
   end
diff --git a/app/models/follow.rb b/app/models/follow.rb
index eaf8445f3bfb0c9243c6b1ebb4321e1bfc7bc8a5..87fa114253b4e6b4b454cfd53d9f65c937646e23 100644
--- a/app/models/follow.rb
+++ b/app/models/follow.rb
@@ -16,15 +16,13 @@ class Follow < ApplicationRecord
   include Paginable
   include RelationshipCacheable
 
-  belongs_to :account, counter_cache: :following_count
-
-  belongs_to :target_account,
-             class_name: 'Account',
-             counter_cache: :followers_count
+  belongs_to :account
+  belongs_to :target_account, class_name: 'Account'
 
   has_one :notification, as: :activity, dependent: :destroy
 
   validates :account_id, uniqueness: { scope: :target_account_id }
+  validates_with FollowLimitValidator, on: :create
 
   scope :recent, -> { reorder(id: :desc) }
 
@@ -32,11 +30,33 @@ class Follow < ApplicationRecord
     false # Force uri_for to use uri attribute
   end
 
+  def revoke_request!
+    FollowRequest.create!(account: account, target_account: target_account, show_reblogs: show_reblogs, uri: uri)
+    destroy!
+  end
+
   before_validation :set_uri, only: :create
+  after_create :increment_cache_counters
+  after_destroy :remove_endorsements
+  after_destroy :decrement_cache_counters
 
   private
 
   def set_uri
     self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
   end
+
+  def remove_endorsements
+    AccountPin.where(target_account_id: target_account_id, account_id: account_id).delete_all
+  end
+
+  def increment_cache_counters
+    account&.increment_count!(:following_count)
+    target_account&.increment_count!(:followers_count)
+  end
+
+  def decrement_cache_counters
+    account&.decrement_count!(:following_count)
+    target_account&.decrement_count!(:followers_count)
+  end
 end
diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb
index 9c4875564b29a6d6293d6534b5aa74c2c9e6e8ed..c5451a0507ac58df3894a9796ba13cdcee4b8731 100644
--- a/app/models/follow_request.rb
+++ b/app/models/follow_request.rb
@@ -22,6 +22,7 @@ class FollowRequest < ApplicationRecord
   has_one :notification, as: :activity, dependent: :destroy
 
   validates :account_id, uniqueness: { scope: :target_account_id }
+  validates_with FollowLimitValidator, on: :create
 
   def authorize!
     account.follow!(target_account, reblogs: show_reblogs, uri: uri)
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index 723480bddb4c13bf631e2063c3c1b109876a30de..eca71bf6214f466efb2782c5b12a04fd19a985f0 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -10,6 +10,8 @@ class Form::AdminSettings
     :site_contact_email=,
     :site_title,
     :site_title=,
+    :site_short_description,
+    :site_short_description=,
     :site_description,
     :site_description=,
     :site_extended_description,
@@ -28,6 +30,8 @@ class Form::AdminSettings
     :show_staff_badge=,
     :bootstrap_timeline_accounts,
     :bootstrap_timeline_accounts=,
+    :theme,
+    :theme=,
     :min_invite_role,
     :min_invite_role=,
     :activity_api_enabled,
@@ -38,6 +42,10 @@ class Form::AdminSettings
     :show_known_fediverse_at_about_page=,
     :preview_sensitive_media,
     :preview_sensitive_media=,
+    :custom_css,
+    :custom_css=,
+    :profile_directory,
+    :profile_directory=,
     to: Setting
   )
 end
diff --git a/app/models/form/status_batch.rb b/app/models/form/status_batch.rb
index 4f08a3049732168183f9df9d26e20f9c8b3d4c36..89872806754ed9da47289f45dae468a970dce910 100644
--- a/app/models/form/status_batch.rb
+++ b/app/models/form/status_batch.rb
@@ -6,8 +6,6 @@ class Form::StatusBatch
 
   attr_accessor :status_ids, :action, :current_account
 
-  ACTION_TYPE = %w(nsfw_on nsfw_off delete).freeze
-
   def save
     case action
     when 'nsfw_on', 'nsfw_off'
@@ -23,7 +21,7 @@ class Form::StatusBatch
     media_attached_status_ids = MediaAttachment.where(status_id: status_ids).pluck(:status_id)
 
     ApplicationRecord.transaction do
-      Status.where(id: media_attached_status_ids).find_each do |status|
+      Status.where(id: media_attached_status_ids).reorder(nil).find_each do |status|
         status.update!(sensitive: sensitive)
         log_action :update, status
       end
@@ -35,7 +33,7 @@ class Form::StatusBatch
   end
 
   def delete_statuses
-    Status.where(id: status_ids).find_each do |status|
+    Status.where(id: status_ids).reorder(nil).find_each do |status|
       RemovalWorker.perform_async(status.id)
       log_action :destroy, status
     end
diff --git a/app/models/home_feed.rb b/app/models/home_feed.rb
index b943a34ce19ab4889ca13c801cbde91a97efe01a..ba7564983b0f8bc9820759773c7d53b0ec075578 100644
--- a/app/models/home_feed.rb
+++ b/app/models/home_feed.rb
@@ -7,9 +7,9 @@ class HomeFeed < Feed
     @account = account
   end
 
-  def get(limit, max_id = nil, since_id = nil)
+  def get(limit, max_id = nil, since_id = nil, min_id = nil)
     if redis.exists("account:#{@account.id}:regeneration")
-      from_database(limit, max_id, since_id)
+      from_database(limit, max_id, since_id, min_id)
     else
       super
     end
@@ -17,9 +17,9 @@ class HomeFeed < Feed
 
   private
 
-  def from_database(limit, max_id, since_id)
+  def from_database(limit, max_id, since_id, min_id)
     Status.as_home_timeline(@account)
-          .paginate_by_max_id(limit, max_id, since_id)
+          .paginate_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
           .reject { |status| FeedManager.instance.filter?(:home, status, @account.id) }
   end
 end
diff --git a/app/models/identity.rb b/app/models/identity.rb
index a5e0c09ec14d416afdc4b2e1584f0f01890b800c..8cc65aef413d1330a5c338e64d11287a19a2e4c1 100644
--- a/app/models/identity.rb
+++ b/app/models/identity.rb
@@ -3,12 +3,12 @@
 #
 # Table name: identities
 #
-#  id         :integer          not null, primary key
-#  user_id    :integer
 #  provider   :string           default(""), not null
 #  uid        :string           default(""), not null
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
+#  id         :bigint(8)        not null, primary key
+#  user_id    :bigint(8)
 #
 
 class Identity < ApplicationRecord
diff --git a/app/models/instance.rb b/app/models/instance.rb
index 6d5c9c2ab605008da96b0fa50fa2ae4684bc6e40..7448d465c3c4eaf90a48b820d13352fdf3f4f3b8 100644
--- a/app/models/instance.rb
+++ b/app/models/instance.rb
@@ -3,10 +3,23 @@
 class Instance
   include ActiveModel::Model
 
-  attr_accessor :domain, :accounts_count
+  attr_accessor :domain, :accounts_count, :domain_block
 
-  def initialize(account)
-    @domain = account.domain
-    @accounts_count = account.accounts_count
+  def initialize(resource)
+    @domain         = resource.domain
+    @accounts_count = resource.accounts_count
+    @domain_block   = resource.is_a?(DomainBlock) ? resource : DomainBlock.find_by(domain: 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) }
+  end
+
+  def to_param
+    domain
+  end
+
+  def cache_key
+    domain
   end
 end
diff --git a/app/models/instance_filter.rb b/app/models/instance_filter.rb
index 5073cf1faa48a06e95b2dbbb75ef69423a3de465..3483d8cd6e996ec7104909e1d37a7761c56a8372 100644
--- a/app/models/instance_filter.rb
+++ b/app/models/instance_filter.rb
@@ -8,21 +8,10 @@ class InstanceFilter
   end
 
   def results
-    scope = Account.remote.by_domain_accounts
-    params.each do |key, value|
-      scope.merge!(scope_for(key, value)) if value.present?
-    end
-    scope
-  end
-
-  private
-
-  def scope_for(key, value)
-    case key.to_s
-    when 'domain_name'
-      Account.matches_domain(value)
+    if params[:limited].present?
+      DomainBlock.order(id: :desc)
     else
-      raise "Unknown filter: #{key}"
+      Account.remote.by_domain_accounts
     end
   end
 end
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index f9a8f322ead50e48bb20030b08569b51059875bc..6b939124fa44e7378222632b5fa7a107073e1542 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -3,20 +3,21 @@
 #
 # Table name: media_attachments
 #
-#  id                :bigint(8)        not null, primary key
-#  status_id         :bigint(8)
-#  file_file_name    :string
-#  file_content_type :string
-#  file_file_size    :integer
-#  file_updated_at   :datetime
-#  remote_url        :string           default(""), not null
-#  created_at        :datetime         not null
-#  updated_at        :datetime         not null
-#  shortcode         :string
-#  type              :integer          default("image"), not null
-#  file_meta         :json
-#  account_id        :bigint(8)
-#  description       :text
+#  id                  :bigint(8)        not null, primary key
+#  status_id           :bigint(8)
+#  file_file_name      :string
+#  file_content_type   :string
+#  file_file_size      :integer
+#  file_updated_at     :datetime
+#  remote_url          :string           default(""), not null
+#  created_at          :datetime         not null
+#  updated_at          :datetime         not null
+#  shortcode           :string
+#  type                :integer          default("image"), not null
+#  file_meta           :json
+#  account_id          :bigint(8)
+#  description         :text
+#  scheduled_status_id :bigint(8)
 #
 
 class MediaAttachment < ApplicationRecord
@@ -25,19 +26,20 @@ class MediaAttachment < ApplicationRecord
   enum type: [:image, :gifv, :video, :unknown]
 
   IMAGE_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif'].freeze
-  VIDEO_FILE_EXTENSIONS = ['.webm', '.mp4', '.m4v'].freeze
+  VIDEO_FILE_EXTENSIONS = ['.webm', '.mp4', '.m4v', '.mov'].freeze
 
-  IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
-  VIDEO_MIME_TYPES = ['video/webm', 'video/mp4'].freeze
+  IMAGE_MIME_TYPES             = ['image/jpeg', 'image/png', 'image/gif'].freeze
+  VIDEO_MIME_TYPES             = ['video/webm', 'video/mp4', 'video/quicktime'].freeze
+  VIDEO_CONVERTIBLE_MIME_TYPES = ['video/webm', 'video/quicktime'].freeze
 
   IMAGE_STYLES = {
     original: {
-      geometry: '1280x1280>',
+      pixels: 1_638_400, # 1280x1280px
       file_geometry_parser: FastGeometryParser,
     },
 
     small: {
-      geometry: '400x400>',
+      pixels: 160_000, # 400x400px
       file_geometry_parser: FastGeometryParser,
     },
   }.freeze
@@ -54,10 +56,30 @@ class MediaAttachment < ApplicationRecord
     },
   }.freeze
 
-  LIMIT = 8.megabytes
+  VIDEO_FORMAT = {
+    format: 'mp4',
+    convert_options: {
+      output: {
+        'loglevel' => 'fatal',
+        'movflags' => 'faststart',
+        'pix_fmt'  => 'yuv420p',
+        'vf'       => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',
+        'vsync'    => 'cfr',
+        'c:v'      => 'h264',
+        'b:v'      => '500K',
+        'maxrate'  => '1300K',
+        'bufsize'  => '1300K',
+        'crf'      => 18,
+      },
+    },
+  }.freeze
+
+  IMAGE_LIMIT = 8.megabytes
+  VIDEO_LIMIT = 40.megabytes
 
-  belongs_to :account, inverse_of: :media_attachments, optional: true
-  belongs_to :status,  inverse_of: :media_attachments, optional: true
+  belongs_to :account,          inverse_of: :media_attachments, optional: true
+  belongs_to :status,           inverse_of: :media_attachments, optional: true
+  belongs_to :scheduled_status, inverse_of: :media_attachments, optional: true
 
   has_attached_file :file,
                     styles: ->(f) { file_styles f },
@@ -65,16 +87,17 @@ class MediaAttachment < ApplicationRecord
                     convert_options: { all: '-quality 90 -strip' }
 
   validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES
-  validates_attachment_size :file, less_than: LIMIT
-  remotable_attachment :file, LIMIT
+  validates_attachment_size :file, less_than: IMAGE_LIMIT, unless: :video?
+  validates_attachment_size :file, less_than: VIDEO_LIMIT, if: :video?
+  remotable_attachment :file, VIDEO_LIMIT
 
   include Attachmentable
 
   validates :account, presence: true
   validates :description, length: { maximum: 420 }, if: :local?
 
-  scope :attached,   -> { where.not(status_id: nil) }
-  scope :unattached, -> { where(status_id: nil) }
+  scope :attached,   -> { where.not(status_id: nil).or(where.not(scheduled_status_id: nil)) }
+  scope :unattached, -> { where(status_id: nil, scheduled_status_id: nil) }
   scope :local,      -> { where(remote_url: '') }
   scope :remote,     -> { where.not(remote_url: '') }
 
@@ -110,6 +133,7 @@ class MediaAttachment < ApplicationRecord
     "#{x},#{y}"
   end
 
+  after_commit :reset_parent_cache, on: :update
   before_create :prepare_description, unless: :local?
   before_create :set_shortcode
   before_post_process :set_type_and_extension
@@ -122,25 +146,15 @@ class MediaAttachment < ApplicationRecord
       if f.instance.file_content_type == 'image/gif'
         {
           small: IMAGE_STYLES[:small],
-          original: {
-            format: 'mp4',
-            convert_options: {
-              output: {
-                'movflags' => 'faststart',
-                'pix_fmt'  => 'yuv420p',
-                'vf'       => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',
-                'vsync'    => 'cfr',
-                'c:v'      => 'h264',
-                'b:v'      => '500K',
-                'maxrate'  => '1300K',
-                'bufsize'  => '1300K',
-                'crf'      => 18,
-              },
-            },
-          },
+          original: VIDEO_FORMAT,
         }
       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
         VIDEO_STYLES
       end
@@ -152,7 +166,7 @@ class MediaAttachment < ApplicationRecord
       elsif VIDEO_MIME_TYPES.include? f.file_content_type
         [:video_transcoder]
       else
-        [:thumbnail]
+        [:lazy_thumbnail]
       end
     end
   end
@@ -220,4 +234,9 @@ class MediaAttachment < ApplicationRecord
       bitrate: movie.bitrate,
     }
   end
+
+  def reset_parent_cache
+    return if status_id.nil?
+    Rails.cache.delete("statuses/#{status_id}")
+  end
 end
diff --git a/app/models/mention.rb b/app/models/mention.rb
index 8ab886b18434028f17cbc40486c6a269e599f83e..d01a88e32eb976c16b885a9c8fb406c3ab873188 100644
--- a/app/models/mention.rb
+++ b/app/models/mention.rb
@@ -8,6 +8,7 @@
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
 #  account_id :bigint(8)
+#  silent     :boolean          default(FALSE), not null
 #
 
 class Mention < ApplicationRecord
@@ -18,10 +19,17 @@ class Mention < ApplicationRecord
 
   validates :account, uniqueness: { scope: :status }
 
+  scope :active, -> { where(silent: false) }
+  scope :silent, -> { where(silent: true) }
+
   delegate(
     :username,
     :acct,
     to: :account,
     prefix: true
   )
+
+  def active?
+    !silent?
+  end
 end
diff --git a/app/models/notification.rb b/app/models/notification.rb
index 4f6ec8e8ea56ac72840affe15b84486c7f71158c..2f0a9b78c7a040d0065ad8256db0229b216045b9 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -24,7 +24,7 @@ class Notification < ApplicationRecord
     favourite:      'Favourite',
   }.freeze
 
-  STATUS_INCLUDES = [:account, :application, :stream_entry, :media_attachments, :tags, mentions: :account, reblog: [:stream_entry, :account, :application, :media_attachments, :tags, mentions: :account]].freeze
+  STATUS_INCLUDES = [:account, :application, :media_attachments, :tags, active_mentions: :account, reblog: [:account, :application, :media_attachments, :tags, active_mentions: :account]].freeze
 
   belongs_to :account, optional: true
   belongs_to :from_account, class_name: 'Account', optional: true
@@ -39,8 +39,6 @@ class Notification < ApplicationRecord
   validates :account_id, uniqueness: { scope: [:activity_type, :activity_id] }
   validates :activity_type, inclusion: { in: TYPE_CLASS_MAP.values }
 
-  scope :cache_ids, -> { select(:id, :updated_at, :activity_type, :activity_id) }
-
   scope :browserable, ->(exclude_types = []) {
     types = TYPE_CLASS_MAP.values - activity_types_from_types(exclude_types + [:follow_request])
     where(activity_type: types)
@@ -68,12 +66,16 @@ class Notification < ApplicationRecord
   end
 
   class << self
+    def cache_ids
+      select(:id, :updated_at, :activity_type, :activity_id)
+    end
+
     def reload_stale_associations!(cached_items)
       account_ids = (cached_items.map(&:from_account_id) + cached_items.map { |item| item.target_status&.account_id }.compact).uniq
 
       return if account_ids.empty?
 
-      accounts = Account.where(id: account_ids).map { |a| [a.id, a] }.to_h
+      accounts = Account.where(id: account_ids).includes(:account_stat).each_with_object({}) { |a, h| h[a.id] = a }
 
       cached_items.each do |item|
         item.from_account = accounts[item.from_account_id]
diff --git a/app/models/relay.rb b/app/models/relay.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7478c110d4557552a8bdd13192d77a1933787070
--- /dev/null
+++ b/app/models/relay.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: relays
+#
+#  id                 :bigint(8)        not null, primary key
+#  inbox_url          :string           default(""), not null
+#  follow_activity_id :string
+#  created_at         :datetime         not null
+#  updated_at         :datetime         not null
+#  state              :integer          default("idle"), not null
+#
+
+class Relay < ApplicationRecord
+  PRESET_RELAY = 'https://relay.joinmastodon.org/inbox'
+
+  validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url?
+
+  enum state: [:idle, :pending, :accepted, :rejected]
+
+  scope :enabled, -> { accepted }
+
+  before_destroy :ensure_disabled
+
+  alias enabled? accepted?
+
+  def enable!
+    activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
+    payload     = Oj.dump(follow_activity(activity_id))
+
+    update!(state: :pending, follow_activity_id: activity_id)
+    ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
+  end
+
+  def disable!
+    activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
+    payload     = Oj.dump(unfollow_activity(activity_id))
+
+    update!(state: :idle, follow_activity_id: nil)
+    ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
+  end
+
+  private
+
+  def follow_activity(activity_id)
+    {
+      '@context': ActivityPub::TagManager::CONTEXT,
+      id: activity_id,
+      type: 'Follow',
+      actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
+      object: ActivityPub::TagManager::COLLECTIONS[:public],
+    }
+  end
+
+  def unfollow_activity(activity_id)
+    {
+      '@context': ActivityPub::TagManager::CONTEXT,
+      id: activity_id,
+      type: 'Undo',
+      actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
+      object: {
+        id: follow_activity_id,
+        type: 'Follow',
+        actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
+        object: ActivityPub::TagManager::COLLECTIONS[:public],
+      },
+    }
+  end
+
+  def some_local_account
+    @some_local_account ||= Account.representative
+  end
+
+  def ensure_disabled
+    return unless enabled?
+    disable!
+  end
+end
diff --git a/app/models/remote_follow.rb b/app/models/remote_follow.rb
index 070144e2d81dc20f309470234977d8b5084a14bd..2537de36c7b3f3ef8b6526114ebefd8196b4d293 100644
--- a/app/models/remote_follow.rb
+++ b/app/models/remote_follow.rb
@@ -22,6 +22,10 @@ class RemoteFollow
     addressable_template.expand(uri: account.local_username_and_domain).to_s
   end
 
+  def interact_address_for(status)
+    addressable_template.expand(uri: ActivityPub::TagManager.instance.uri_for(status)).to_s
+  end
+
   private
 
   def populate_template
diff --git a/app/models/report.rb b/app/models/report.rb
index efe385b2dbb855e2882ee8c3b9f35f35c1fcdcb3..2804020f5273bcfca453adea85dc50230dab733e 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -60,6 +60,10 @@ class Report < ApplicationRecord
     !action_taken?
   end
 
+  def unresolved_siblings?
+    Report.where.not(id: id).where(target_account_id: target_account_id).unresolved.exists?
+  end
+
   def history
     time_range = created_at..updated_at
 
diff --git a/app/models/report_note.rb b/app/models/report_note.rb
index 54b416577a14ee3f176a654188977599c8a1f084..6d7167e0edbc8cb9fa63cfa9774ae53a599ebe39 100644
--- a/app/models/report_note.rb
+++ b/app/models/report_note.rb
@@ -15,7 +15,7 @@ class ReportNote < ApplicationRecord
   belongs_to :account
   belongs_to :report, inverse_of: :notes, touch: true
 
-  scope :latest, -> { reorder('created_at ASC') }
+  scope :latest, -> { reorder(created_at: :desc) }
 
   validates :content, presence: true, length: { maximum: 500 }
 end
diff --git a/app/models/scheduled_status.rb b/app/models/scheduled_status.rb
new file mode 100644
index 0000000000000000000000000000000000000000..27f0cbd280cbf2c3c22110a0cda25820f68fc991
--- /dev/null
+++ b/app/models/scheduled_status.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: scheduled_statuses
+#
+#  id           :bigint(8)        not null, primary key
+#  account_id   :bigint(8)
+#  scheduled_at :datetime
+#  params       :jsonb
+#
+
+class ScheduledStatus < ApplicationRecord
+  include Paginable
+
+  TOTAL_LIMIT = 300
+  DAILY_LIMIT = 25
+
+  belongs_to :account, inverse_of: :scheduled_statuses
+  has_many :media_attachments, inverse_of: :scheduled_status, dependent: :nullify
+
+  validate :validate_future_date
+  validate :validate_total_limit
+  validate :validate_daily_limit
+
+  private
+
+  def validate_future_date
+    errors.add(:scheduled_at, I18n.t('scheduled_statuses.too_soon')) if scheduled_at.present? && scheduled_at <= Time.now.utc + PostStatusService::MIN_SCHEDULE_OFFSET
+  end
+
+  def validate_total_limit
+    errors.add(:base, I18n.t('scheduled_statuses.over_total_limit', limit: TOTAL_LIMIT)) if account.scheduled_statuses.count >= TOTAL_LIMIT
+  end
+
+  def validate_daily_limit
+    errors.add(:base, I18n.t('scheduled_statuses.over_daily_limit', limit: DAILY_LIMIT)) if account.scheduled_statuses.where('scheduled_at::date = ?::date', scheduled_at).count >= DAILY_LIMIT
+  end
+end
diff --git a/app/models/setting.rb b/app/models/setting.rb
index 033d09fd58022eff94b93bb6259f1048cadbac8c..a5878e96a21cc54ca74dfb86ddcf9aff7f745a7d 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -40,7 +40,7 @@ class Setting < RailsSettings::Base
 
     def all_as_records
       vars    = thing_scoped
-      records = vars.map { |r| [r.var, r] }.to_h
+      records = vars.each_with_object({}) { |r, h| h[r.var] = r }
 
       default_settings.each do |key, default_value|
         next if records.key?(key) || default_value.is_a?(Hash)
diff --git a/app/models/status.rb b/app/models/status.rb
index e7dd0df29e0d66588d680513127a12d020b4ab64..035423b40289d726ce4c7c1c66c73cdb9c5fc6c9 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -15,8 +15,6 @@
 #  visibility             :integer          default("public"), not null
 #  spoiler_text           :text             default(""), not null
 #  reply                  :boolean          default(FALSE), not null
-#  favourites_count       :integer          default(0), not null
-#  reblogs_count          :integer          default(0), not null
 #  language               :string
 #  conversation_id        :bigint(8)
 #  local                  :boolean
@@ -26,6 +24,8 @@
 #
 
 class Status < ApplicationRecord
+  before_destroy :unlink_from_conversations
+
   include Paginable
   include Streamable
   include Cacheable
@@ -37,7 +37,7 @@ class Status < ApplicationRecord
 
   update_index('statuses#status', :proper) if Chewy.enabled?
 
-  enum visibility: [:public, :unlisted, :private, :direct], _suffix: :visibility
+  enum visibility: [:public, :unlisted, :private, :direct, :limited], _suffix: :visibility
 
   belongs_to :application, class_name: 'Doorkeeper::Application', optional: true
 
@@ -51,7 +51,8 @@ class Status < ApplicationRecord
   has_many :favourites, inverse_of: :status, dependent: :destroy
   has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy
   has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :thread
-  has_many :mentions, dependent: :destroy
+  has_many :mentions, dependent: :destroy, inverse_of: :status
+  has_many :active_mentions, -> { active }, class_name: 'Mention', inverse_of: :status
   has_many :media_attachments, dependent: :nullify
 
   has_and_belongs_to_many :tags
@@ -59,6 +60,7 @@ 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
 
   validates :uri, uniqueness: true, presence: true, unless: :local?
   validates :text, presence: true, unless: -> { with_media? || reblog? }
@@ -80,8 +82,39 @@ class Status < ApplicationRecord
   scope :including_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced: true }) }
   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) }
-
-  cache_associated :account, :application, :media_attachments, :conversation, :tags, :stream_entry, mentions: :account, reblog: [:account, :application, :stream_entry, :tags, :media_attachments, :conversation, mentions: :account], thread: :account
+  scope :tagged_with_all, ->(tags) {
+    Array(tags).map(&:id).map(&:to_i).reduce(self) do |result, id|
+      result.joins("INNER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}")
+    end
+  }
+  scope :tagged_with_none, ->(tags) {
+    Array(tags).map(&:id).map(&:to_i).reduce(self) do |result, id|
+      result.joins("LEFT OUTER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}")
+            .where("t#{id}.tag_id IS NULL")
+    end
+  }
+
+  cache_associated :application,
+                   :media_attachments,
+                   :conversation,
+                   :status_stat,
+                   :tags,
+                   :preview_cards,
+                   :stream_entry,
+                   account: :account_stat,
+                   active_mentions: { account: :account_stat },
+                   reblog: [
+                     :application,
+                     :stream_entry,
+                     :tags,
+                     :preview_cards,
+                     :media_attachments,
+                     :conversation,
+                     :status_stat,
+                     account: :account_stat,
+                     active_mentions: { account: :account_stat },
+                   ],
+                   thread: { account: :account_stat }
 
   delegate :domain, to: :account, prefix: true
 
@@ -143,6 +176,10 @@ class Status < ApplicationRecord
     reblog
   end
 
+  def preview_card
+    preview_cards.first
+  end
+
   def title
     if destroyed?
       "#{account.acct} deleted status"
@@ -152,7 +189,11 @@ class Status < ApplicationRecord
   end
 
   def hidden?
-    private_visibility? || direct_visibility?
+    private_visibility? || direct_visibility? || limited_visibility?
+  end
+
+  def distributable?
+    public_visibility? || unlisted_visibility?
   end
 
   def with_media?
@@ -175,8 +216,28 @@ class Status < ApplicationRecord
     @marked_for_mass_destruction
   end
 
-  after_create  :increment_counter_caches
-  after_destroy :decrement_counter_caches
+  def replies_count
+    status_stat&.replies_count || 0
+  end
+
+  def reblogs_count
+    status_stat&.reblogs_count || 0
+  end
+
+  def favourites_count
+    status_stat&.favourites_count || 0
+  end
+
+  def increment_count!(key)
+    update_status_stat!(key => public_send(key) + 1)
+  end
+
+  def decrement_count!(key)
+    update_status_stat!(key => [public_send(key) - 1, 0].max)
+  end
+
+  after_create_commit  :increment_counter_caches
+  after_destroy_commit :decrement_counter_caches
 
   after_create_commit :store_uri, if: :local?
   after_create_commit :update_statistics, if: :local?
@@ -190,6 +251,10 @@ class Status < ApplicationRecord
   before_validation :set_local
 
   class << self
+    def selectable_visibilities
+      visibilities.keys - %w(direct limited)
+    end
+
     def in_chosen_languages(account)
       where(language: nil).or where(language: account.chosen_languages)
     end
@@ -200,7 +265,7 @@ class Status < ApplicationRecord
 
     def as_direct_timeline(account, limit = 20, max_id = nil, since_id = nil, cache_ids = false)
       # direct timeline is mix of direct message from_me and to_me.
-      # 2 querys are executed with pagination.
+      # 2 queries are executed with pagination.
       # constant expression using arel_table is required for partial index
 
       # _from_me part does not require any timeline filters
@@ -256,19 +321,19 @@ class Status < ApplicationRecord
     end
 
     def favourites_map(status_ids, account_id)
-      Favourite.select('status_id').where(status_id: status_ids).where(account_id: account_id).map { |f| [f.status_id, true] }.to_h
+      Favourite.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |f, h| h[f.status_id] = true }
     end
 
     def reblogs_map(status_ids, account_id)
-      select('reblog_of_id').where(reblog_of_id: status_ids).where(account_id: account_id).reorder(nil).map { |s| [s.reblog_of_id, true] }.to_h
+      select('reblog_of_id').where(reblog_of_id: status_ids).where(account_id: account_id).reorder(nil).each_with_object({}) { |s, h| h[s.reblog_of_id] = true }
     end
 
     def mutes_map(conversation_ids, account_id)
-      ConversationMute.select('conversation_id').where(conversation_id: conversation_ids).where(account_id: account_id).map { |m| [m.conversation_id, true] }.to_h
+      ConversationMute.select('conversation_id').where(conversation_id: conversation_ids).where(account_id: account_id).each_with_object({}) { |m, h| h[m.conversation_id] = true }
     end
 
     def pins_map(status_ids, account_id)
-      StatusPin.select('status_id').where(status_id: status_ids).where(account_id: account_id).map { |p| [p.status_id, true] }.to_h
+      StatusPin.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |p, h| h[p.status_id] = true }
     end
 
     def reload_stale_associations!(cached_items)
@@ -283,7 +348,7 @@ class Status < ApplicationRecord
 
       return if account_ids.empty?
 
-      accounts = Account.where(id: account_ids).map { |a| [a.id, a] }.to_h
+      accounts = Account.where(id: account_ids).includes(:account_stat).each_with_object({}) { |a, h| h[a.id] = a }
 
       cached_items.each do |item|
         item.account = accounts[item.account_id]
@@ -343,7 +408,8 @@ class Status < ApplicationRecord
 
     def account_silencing_filter(account)
       if account.silenced?
-        including_silenced_accounts
+        including_myself = left_outer_joins(:account).where(account_id: account.id).references(:accounts)
+        excluding_silenced_accounts.or(including_myself)
       else
         excluding_silenced_accounts
       end
@@ -352,8 +418,15 @@ class Status < ApplicationRecord
 
   private
 
+  def update_status_stat!(attrs)
+    return if marked_for_destruction? || destroyed?
+
+    record = status_stat || build_status_stat
+    record.update(attrs)
+  end
+
   def store_uri
-    update_attribute(:uri, ActivityPub::TagManager.instance.uri_for(self)) if uri.nil?
+    update_column(:uri, ActivityPub::TagManager.instance.uri_for(self)) if uri.nil?
   end
 
   def prepare_contents
@@ -372,6 +445,8 @@ class Status < ApplicationRecord
   end
 
   def set_conversation
+    self.thread = thread.reblog if thread&.reblog?
+
     self.reply = !(in_reply_to_id.nil? && thread.nil?) unless reply
 
     if reply? && !thread.nil?
@@ -402,36 +477,27 @@ class Status < ApplicationRecord
   def increment_counter_caches
     return if direct_visibility?
 
-    if association(:account).loaded?
-      account.update_attribute(:statuses_count, account.statuses_count + 1)
-    else
-      Account.where(id: account_id).update_all('statuses_count = COALESCE(statuses_count, 0) + 1')
-    end
-
-    return unless reblog?
-
-    if association(:reblog).loaded?
-      reblog.update_attribute(:reblogs_count, reblog.reblogs_count + 1)
-    else
-      Status.where(id: reblog_of_id).update_all('reblogs_count = COALESCE(reblogs_count, 0) + 1')
-    end
+    account&.increment_count!(:statuses_count)
+    reblog&.increment_count!(:reblogs_count) if reblog? && (public_visibility? || unlisted_visibility?)
+    thread&.increment_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
   end
 
   def decrement_counter_caches
     return if direct_visibility? || marked_for_mass_destruction?
 
-    if association(:account).loaded?
-      account.update_attribute(:statuses_count, [account.statuses_count - 1, 0].max)
-    else
-      Account.where(id: account_id).update_all('statuses_count = GREATEST(COALESCE(statuses_count, 0) - 1, 0)')
-    end
+    account&.decrement_count!(:statuses_count)
+    reblog&.decrement_count!(:reblogs_count) if reblog? && (public_visibility? || unlisted_visibility?)
+    thread&.decrement_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
+  end
 
-    return unless reblog?
+  def unlink_from_conversations
+    return unless direct_visibility?
 
-    if association(:reblog).loaded?
-      reblog.update_attribute(:reblogs_count, [reblog.reblogs_count - 1, 0].max)
-    else
-      Status.where(id: reblog_of_id).update_all('reblogs_count = GREATEST(COALESCE(reblogs_count, 0) - 1, 0)')
+    mentioned_accounts = mentions.includes(:account).map(&:account)
+    inbox_owners       = mentioned_accounts.select(&:local?) + (account.local? ? [account] : [])
+
+    inbox_owners.each do |inbox_owner|
+      AccountConversation.remove_status(inbox_owner, self)
     end
   end
 end
diff --git a/app/models/status_stat.rb b/app/models/status_stat.rb
new file mode 100644
index 0000000000000000000000000000000000000000..024c467e7150ffc055093fed9cb98612ffdb087f
--- /dev/null
+++ b/app/models/status_stat.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: status_stats
+#
+#  id               :bigint(8)        not null, primary key
+#  status_id        :bigint(8)        not null
+#  replies_count    :bigint(8)        default(0), not null
+#  reblogs_count    :bigint(8)        default(0), not null
+#  favourites_count :bigint(8)        default(0), not null
+#  created_at       :datetime         not null
+#  updated_at       :datetime         not null
+#
+
+class StatusStat < ApplicationRecord
+  belongs_to :status, inverse_of: :status_stat
+
+  after_commit :reset_parent_cache
+
+  private
+
+  def reset_parent_cache
+    Rails.cache.delete("statuses/#{status_id}")
+  end
+end
diff --git a/app/models/stream_entry.rb b/app/models/stream_entry.rb
index a2f273281b6df07e7c5e2c43791114bd01babe86..1a9afc5c7b743264aeec96994b07afefa8ca6caf 100644
--- a/app/models/stream_entry.rb
+++ b/app/models/stream_entry.rb
@@ -48,7 +48,7 @@ class StreamEntry < ApplicationRecord
   end
 
   def mentions
-    orphaned? ? [] : status.mentions.map(&:account)
+    orphaned? ? [] : status.active_mentions.map(&:account)
   end
 
   private
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 4f31f796e6ab13ec752a2842803857db52e313f6..99830ae92c66e95fb9004ba245f878ddf56f99c0 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -11,12 +11,36 @@
 
 class Tag < ApplicationRecord
   has_and_belongs_to_many :statuses
+  has_and_belongs_to_many :accounts
+  has_and_belongs_to_many :sample_accounts, -> { searchable.discoverable.popular.limit(3) }, class_name: 'Account'
+
+  has_one :account_tag_stat, dependent: :destroy
 
   HASHTAG_NAME_RE = '[[:word:]_]*[[:alpha:]_·][[:word:]_]*'
   HASHTAG_RE = /(?:^|[^\/\)\w])#(#{HASHTAG_NAME_RE})/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 }) }
+
+  delegate :accounts_count,
+           :accounts_count=,
+           :increment_count!,
+           :decrement_count!,
+           :hidden?,
+           to: :account_tag_stat
+
+  after_save :save_account_tag_stat
+
+  def account_tag_stat
+    super || build_account_tag_stat
+  end
+
+  def cached_sample_accounts
+    Rails.cache.fetch("#{cache_key}/sample_accounts", expires_in: 12.hours) { sample_accounts }
+  end
+
   def to_param
     name
   end
@@ -43,4 +67,11 @@ class Tag < ApplicationRecord
       Tag.where('lower(name) like lower(?)', pattern).order(:name).limit(limit)
     end
   end
+
+  private
+
+  def save_account_tag_stat
+    return unless account_tag_stat&.changed?
+    account_tag_stat.save
+  end
 end
diff --git a/app/models/tombstone.rb b/app/models/tombstone.rb
new file mode 100644
index 0000000000000000000000000000000000000000..997bb65fd068c4b0f33e8ba03e363e3338de1e4e
--- /dev/null
+++ b/app/models/tombstone.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# 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
+#
+
+class Tombstone < ApplicationRecord
+  belongs_to :account
+end
diff --git a/app/models/trending_tags.rb b/app/models/trending_tags.rb
index c3641d7fd9552b2d4eec2029eacc8823033153d5..3a8be21649b936a2cd5ad02a4e9621472785a8a7 100644
--- a/app/models/trending_tags.rb
+++ b/app/models/trending_tags.rb
@@ -1,7 +1,10 @@
 # frozen_string_literal: true
 
 class TrendingTags
+  KEY                  = 'trending_tags'
   EXPIRE_HISTORY_AFTER = 7.days.seconds
+  EXPIRE_TRENDS_AFTER  = 1.day.seconds
+  THRESHOLD            = 5
 
   class << self
     def record_use!(tag, account, at_time = Time.now.utc)
@@ -9,6 +12,14 @@ class TrendingTags
 
       increment_historical_use!(tag.id, at_time)
       increment_unique_use!(tag.id, account.id, at_time)
+      increment_vote!(tag.id, at_time)
+    end
+
+    def get(limit)
+      key     = "#{KEY}:#{Time.now.utc.beginning_of_day.to_i}"
+      tag_ids = redis.zrevrange(key, 0, limit - 1).map(&:to_i)
+      tags    = Tag.where(id: tag_ids).to_a.each_with_object({}) { |tag, h| h[tag.id] = tag }
+      tag_ids.map { |tag_id| tags[tag_id] }.compact
     end
 
     private
@@ -25,6 +36,22 @@ class TrendingTags
       redis.expire(key, EXPIRE_HISTORY_AFTER)
     end
 
+    def increment_vote!(tag_id, at_time)
+      key      = "#{KEY}:#{at_time.beginning_of_day.to_i}"
+      expected = redis.pfcount("activity:tags:#{tag_id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts").to_f
+      expected = 1.0 if expected.zero?
+      observed = redis.pfcount("activity:tags:#{tag_id}:#{at_time.beginning_of_day.to_i}:accounts").to_f
+
+      if expected > observed || observed < THRESHOLD
+        redis.zrem(key, tag_id.to_s)
+      else
+        score = ((observed - expected)**2) / expected
+        redis.zadd(key, score, tag_id.to_s)
+      end
+
+      redis.expire(key, EXPIRE_TRENDS_AFTER)
+    end
+
     def disallowed_hashtags
       return @disallowed_hashtags if defined?(@disallowed_hashtags)
 
diff --git a/app/models/user.rb b/app/models/user.rb
index c820c553a7fd28d0a81446987f460d6aec86e4f5..5aa5c2b15c4a6be9b64fc822092785dc6a9811cc 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -36,13 +36,21 @@
 #  invite_id                 :bigint(8)
 #  remember_token            :string
 #  chosen_languages          :string           is an Array
+#  created_by_application_id :bigint(8)
 #
 
 class User < ApplicationRecord
   include Settings::Extend
   include Omniauthable
 
-  ACTIVE_DURATION = 7.days
+  # 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
+  # within this time frame. Lowering the duration may improve performance
+  # if lots of people sign up, but not a lot of them check their feed
+  # every day. Raising the duration reduces the amount of expensive
+  # RegenerationWorker jobs that need to be run when those people come
+  # to check their feed
+  ACTIVE_DURATION = ENV.fetch('USER_ACTIVE_DAYS', 7).to_i.days.freeze
 
   devise :two_factor_authenticatable,
          otp_secret_encryption_key: Rails.configuration.x.otp_secret
@@ -59,6 +67,7 @@ class User < ApplicationRecord
 
   belongs_to :account, inverse_of: :user
   belongs_to :invite, counter_cache: :uses, optional: true
+  belongs_to :created_by_application, class_name: 'Doorkeeper::Application', optional: true
   accepts_nested_attributes_for :account
 
   has_many :applications, class_name: 'Doorkeeper::Application', as: :owner
@@ -66,17 +75,19 @@ class User < ApplicationRecord
 
   validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale?
   validates_with BlacklistedEmailValidator, if: :email_changed?
-  validates_with EmailMxValidator, if: :email_changed?
+  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 :confirmed, -> { where.not(confirmed_at: nil) }
+  scope :enabled, -> { where(disabled: false) }
   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 :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) }
-  scope :with_recent_ip_address, ->(value) { where(arel_table[:current_sign_in_ip].eq(value).or(arel_table[:last_sign_in_ip].eq(value))) }
+  scope :emailable, -> { confirmed.enabled.joins(:account).merge(Account.searchable) }
 
   before_validation :sanitize_languages
 
@@ -88,10 +99,10 @@ class User < ApplicationRecord
   has_many :session_activations, dependent: :destroy
 
   delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
-           :reduce_motion, :system_font_ui, :noindex, :theme, :display_sensitive_media, :hide_network,
-           :default_language, to: :settings, prefix: :setting, allow_nil: false
+           :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network,
+           :expand_spoilers, :default_language, :aggregate_reblogs, to: :settings, prefix: :setting, allow_nil: false
 
-  attr_accessor :invite_code
+  attr_reader :invite_code
 
   def pam_conflict(_)
     # block pam login tries on traditional account
@@ -130,6 +141,10 @@ class User < ApplicationRecord
     confirmed_at.present?
   end
 
+  def invited?
+    invite_id.present?
+  end
+
   def staff?
     admin? || moderator?
   end
@@ -209,10 +224,6 @@ class User < ApplicationRecord
     save!
   end
 
-  def active_for_authentication?
-    super && !disabled?
-  end
-
   def setting_default_privacy
     settings.default_privacy || (account.locked? ? 'private' : 'public')
   end
@@ -221,10 +232,18 @@ class User < ApplicationRecord
     settings.notification_emails['digest']
   end
 
+  def allows_report_emails?
+    settings.notification_emails['report']
+  end
+
   def hides_network?
     @hides_network ||= settings.hide_network
   end
 
+  def aggregates_reblogs?
+    @aggregates_reblogs ||= settings.aggregate_reblogs
+  end
+
   def token_for_app(a)
     return nil if a.nil? || a.owner != self
     Doorkeeper::AccessToken
@@ -255,7 +274,7 @@ class User < ApplicationRecord
   end
 
   def invite_code=(code)
-    self.invite  = Invite.find_by(code: code) unless code.blank?
+    self.invite  = Invite.find_by(code: code) if code.present?
     @invite_code = code
   end
 
@@ -284,7 +303,7 @@ class User < ApplicationRecord
       end
 
     if resource.blank?
-      resource = new(email: attributes[:email])
+      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]
@@ -297,7 +316,7 @@ class User < ApplicationRecord
     resource = joins(:account).find_by(accounts: { username: attributes[Devise.ldap_uid.to_sym].first })
 
     if resource.blank?
-      resource = new(email: attributes[:mail].first, account_attributes: { username: attributes[Devise.ldap_uid.to_sym].first })
+      resource = new(email: attributes[:mail].first, agreement: true, account_attributes: { username: attributes[Devise.ldap_uid.to_sym].first })
       resource.ldap_setup(attributes)
     end
 
@@ -309,6 +328,14 @@ class User < ApplicationRecord
     super
   end
 
+  def show_all_media?
+    setting_display_media == 'show_all'
+  end
+
+  def hide_all_media?
+    setting_display_media == 'hide_all'
+  end
+
   protected
 
   def send_devise_notification(notification, *args)
@@ -335,11 +362,16 @@ class User < ApplicationRecord
   end
 
   def regenerate_feed!
-    Redis.current.setnx("account:#{account_id}:regeneration", true) && Redis.current.expire("account:#{account_id}:regeneration", 1.day.seconds)
+    return unless Redis.current.setnx("account:#{account_id}:regeneration", true)
+    Redis.current.expire("account:#{account_id}:regeneration", 1.day.seconds)
     RegenerationWorker.perform_async(account_id)
   end
 
   def needs_feed_update?
     last_sign_in_at < ACTIVE_DURATION.ago
   end
+
+  def validate_email_dns?
+    email_changed? && !(Rails.env.test? || Rails.env.development?)
+  end
 end
diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb
index d19b20c483f66f0adbc7e10653b0bf370fc12680..b57807d1c2bd5a38144cc617d4911eaabeeb5e97 100644
--- a/app/models/web/push_subscription.rb
+++ b/app/models/web/push_subscription.rb
@@ -68,6 +68,9 @@ class Web::PushSubscription < ApplicationRecord
       p256dh: key_p256dh,
       auth: key_auth,
       ttl: ttl,
+      ssl_timeout: 10,
+      open_timeout: 10,
+      read_timeout: 10,
       vapid: {
         subject: "mailto:#{::Setting.site_contact_email}",
         private_key: Rails.configuration.x.vapid_private_key,
diff --git a/app/policies/account_policy.rb b/app/policies/account_policy.rb
index efabe80d0d58bd357431f36aaab41041d450f343..9c145979d6c2c076577a2359139e457d1164e8e5 100644
--- a/app/policies/account_policy.rb
+++ b/app/policies/account_policy.rb
@@ -9,6 +9,10 @@ class AccountPolicy < ApplicationPolicy
     staff?
   end
 
+  def warn?
+    staff? && !record.user&.staff?
+  end
+
   def suspend?
     staff? && !record.user&.staff?
   end
@@ -33,6 +37,10 @@ class AccountPolicy < ApplicationPolicy
     staff?
   end
 
+  def remove_header?
+    staff?
+  end
+
   def subscribe?
     admin?
   end
diff --git a/app/policies/account_warning_preset_policy.rb b/app/policies/account_warning_preset_policy.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bccbd33efd4888ba077f264a7538d617be861be5
--- /dev/null
+++ b/app/policies/account_warning_preset_policy.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AccountWarningPresetPolicy < ApplicationPolicy
+  def index?
+    staff?
+  end
+
+  def create?
+    staff?
+  end
+
+  def update?
+    staff?
+  end
+
+  def destroy?
+    staff?
+  end
+end
diff --git a/app/policies/instance_policy.rb b/app/policies/instance_policy.rb
index d1956e2ded4c3b76946cbd341c85e2d5b110dfcb..a73823556c5ad6ed7b0e23d141ba599a1346bd63 100644
--- a/app/policies/instance_policy.rb
+++ b/app/policies/instance_policy.rb
@@ -5,7 +5,7 @@ class InstancePolicy < ApplicationPolicy
     admin?
   end
 
-  def resubscribe?
+  def show?
     admin?
   end
 end
diff --git a/app/policies/invite_policy.rb b/app/policies/invite_policy.rb
index a2a65f934d9fd2b2769dd917da73ab5ba7cfb6de..14236f78b8c9ab9babd7c0d9c49531dc590c6f6a 100644
--- a/app/policies/invite_policy.rb
+++ b/app/policies/invite_policy.rb
@@ -9,6 +9,10 @@ class InvitePolicy < ApplicationPolicy
     min_required_role?
   end
 
+  def deactivate_all?
+    admin?
+  end
+
   def destroy?
     owner? || (Setting.min_invite_role == 'admin' ? admin? : staff?)
   end
diff --git a/app/policies/relay_policy.rb b/app/policies/relay_policy.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bd75e21977a75b04c2c7e522714b1f4b82fb4d9f
--- /dev/null
+++ b/app/policies/relay_policy.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class RelayPolicy < ApplicationPolicy
+  def update?
+    admin?
+  end
+end
diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb
index 6addc8a8a8ebe770dca60cb56ab784101ec8dcdb..64a5111fc8f899bbb9e4de6b7da99ee3281f70eb 100644
--- a/app/policies/status_policy.rb
+++ b/app/policies/status_policy.rb
@@ -12,7 +12,7 @@ class StatusPolicy < ApplicationPolicy
   end
 
   def show?
-    if direct?
+    if requires_mention?
       owned? || mention_exists?
     elsif private?
       owned? || following_author? || mention_exists?
@@ -22,7 +22,7 @@ class StatusPolicy < ApplicationPolicy
   end
 
   def reblog?
-    !direct? && (!private? || owned?) && show? && !blocking_author?
+    !requires_mention? && (!private? || owned?) && show? && !blocking_author?
   end
 
   def favourite?
@@ -41,8 +41,8 @@ class StatusPolicy < ApplicationPolicy
 
   private
 
-  def direct?
-    record.direct_visibility?
+  def requires_mention?
+    record.direct_visibility? || record.limited_visibility?
   end
 
   def owned?
diff --git a/app/policies/tag_policy.rb b/app/policies/tag_policy.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c63de01dbe9ef4a34de76da9b90c77438928c8e4
--- /dev/null
+++ b/app/policies/tag_policy.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class TagPolicy < ApplicationPolicy
+  def index?
+    staff?
+  end
+
+  def hide?
+    staff?
+  end
+
+  def unhide?
+    staff?
+  end
+end
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index dabdf707a4b3df7eefdb1dbae72ce2d74f7913c3..57af5c61c86b32b7cd32aacdcbde5462de9d4145 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -18,11 +18,11 @@ class UserPolicy < ApplicationPolicy
   end
 
   def enable?
-    admin?
+    staff?
   end
 
   def disable?
-    admin? && !record.admin?
+    staff? && !record.admin?
   end
 
   def promote?
diff --git a/app/presenters/account_relationships_presenter.rb b/app/presenters/account_relationships_presenter.rb
index b1e99b31b7c3641c23197c2ba8524679e7862ffc..e4aaa65f6ff706fb742178c290861f3d83b9b878 100644
--- a/app/presenters/account_relationships_presenter.rb
+++ b/app/presenters/account_relationships_presenter.rb
@@ -2,7 +2,8 @@
 
 class AccountRelationshipsPresenter
   attr_reader :following, :followed_by, :blocking,
-              :muting, :requested, :domain_blocking
+              :muting, :requested, :domain_blocking,
+              :endorsed
 
   def initialize(account_ids, current_account_id, **options)
     @account_ids        = account_ids.map { |a| a.is_a?(Account) ? a.id : a }
@@ -14,6 +15,7 @@ class AccountRelationshipsPresenter
     @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))
+    @endorsed        = cached[:endorsed].merge(Account.endorsed_map(@uncached_account_ids, @current_account_id))
 
     cache_uncached!
 
@@ -23,6 +25,7 @@ class AccountRelationshipsPresenter
     @muting.merge!(options[:muting_map] || {})
     @requested.merge!(options[:requested_map] || {})
     @domain_blocking.merge!(options[:domain_blocking_map] || {})
+    @endorsed.merge!(options[:endorsed_map] || {})
   end
 
   private
@@ -37,6 +40,7 @@ class AccountRelationshipsPresenter
       muting: {},
       requested: {},
       domain_blocking: {},
+      endorsed: {},
     }
 
     @uncached_account_ids = []
@@ -63,6 +67,7 @@ class AccountRelationshipsPresenter
         muting:          { account_id => muting[account_id] },
         requested:       { account_id => requested[account_id] },
         domain_blocking: { account_id => domain_blocking[account_id] },
+        endorsed:        { account_id => endorsed[account_id] },
       }
 
       Rails.cache.write("relationship:#{@current_account_id}:#{account_id}", maps_for_account, expires_in: 1.day)
diff --git a/app/presenters/instance_presenter.rb b/app/presenters/instance_presenter.rb
index e4972c9623c71eabee9185f0d62f28645e805cbf..dc77162d441aa3ee8e8f641cc5dacc6e3240a4f1 100644
--- a/app/presenters/instance_presenter.rb
+++ b/app/presenters/instance_presenter.rb
@@ -6,6 +6,7 @@ class InstancePresenter
     :site_contact_email,
     :open_registrations,
     :site_title,
+    :site_short_description,
     :site_description,
     :site_extended_description,
     :site_terms,
@@ -13,15 +14,15 @@ class InstancePresenter
   )
 
   def contact_account
-    Account.find_local(Setting.site_contact_username)
+    Account.find_local(Setting.site_contact_username.gsub(/\A@/, ''))
   end
 
   def user_count
-    Rails.cache.fetch('user_count') { User.confirmed.count }
+    Rails.cache.fetch('user_count') { User.confirmed.joins(:account).merge(Account.without_suspended).count }
   end
 
   def status_count
-    Rails.cache.fetch('local_status_count') { Account.local.sum(:statuses_count) }
+    Rails.cache.fetch('local_status_count') { Account.local.joins(:account_stat).sum('account_stats.statuses_count') }.to_i
   end
 
   def domain_count
@@ -43,4 +44,8 @@ class InstancePresenter
   def hero
     @hero ||= Rails.cache.fetch('site_uploads/hero') { SiteUpload.find_by(var: 'hero') }
   end
+
+  def mascot
+    @mascot ||= Rails.cache.fetch('site_uploads/mascot') { SiteUpload.find_by(var: 'mascot') }
+  end
 end
diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb
index 41c9aa44e81da49eeafb85123fb6c46b24cd7dc6..6746c1782929a94fb622de10ede547f2c822c271 100644
--- a/app/serializers/activitypub/actor_serializer.rb
+++ b/app/serializers/activitypub/actor_serializer.rb
@@ -14,6 +14,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
   has_many :virtual_attachments, key: :attachment
 
   attribute :moved_to, if: :moved?
+  attribute :also_known_as, if: :also_known_as?
 
   class EndpointsSerializer < ActiveModel::Serializer
     include RoutingHelper
@@ -93,11 +94,11 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
   end
 
   def avatar_exists?
-    object.avatar.exists?
+    object.avatar?
   end
 
   def header_exists?
-    object.header.exists?
+    object.header?
   end
 
   def manually_approves_followers
@@ -105,7 +106,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
   end
 
   def virtual_tags
-    object.emojis
+    object.emojis + object.tags
   end
 
   def virtual_attachments
@@ -116,9 +117,31 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
     ActivityPub::TagManager.instance.uri_for(object.moved_to_account)
   end
 
+  def also_known_as?
+    !object.also_known_as.empty?
+  end
+
   class CustomEmojiSerializer < ActivityPub::EmojiSerializer
   end
 
+  class TagSerializer < ActiveModel::Serializer
+    include RoutingHelper
+
+    attributes :type, :href, :name
+
+    def type
+      'Hashtag'
+    end
+
+    def href
+      explore_hashtag_url(object)
+    end
+
+    def name
+      "##{object.name}"
+    end
+  end
+
   class Account::FieldSerializer < ActiveModel::Serializer
     attributes :type, :name, :value
 
diff --git a/app/serializers/activitypub/delete_actor_serializer.rb b/app/serializers/activitypub/delete_actor_serializer.rb
index dfea9db4abf16f4a20a7bce5c6a41eeb9419f1d3..ddf59be9709ef1cc21af267f935fbb28611ac1cb 100644
--- a/app/serializers/activitypub/delete_actor_serializer.rb
+++ b/app/serializers/activitypub/delete_actor_serializer.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
-  attributes :id, :type, :actor
+  attributes :id, :type, :actor, :to
   attribute :virtual_object, key: :object
 
   def id
@@ -19,4 +19,8 @@ class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
   def virtual_object
     actor
   end
+
+  def to
+    [ActivityPub::TagManager::COLLECTIONS[:public]]
+  end
 end
diff --git a/app/serializers/activitypub/delete_serializer.rb b/app/serializers/activitypub/delete_serializer.rb
index 2bb65135f7c5c3ca7aca4ac2877f86926b6be1be..5012a8383ff517003906f65474636f6b7e2da4db 100644
--- a/app/serializers/activitypub/delete_serializer.rb
+++ b/app/serializers/activitypub/delete_serializer.rb
@@ -17,7 +17,7 @@ class ActivityPub::DeleteSerializer < ActiveModel::Serializer
     end
   end
 
-  attributes :id, :type, :actor
+  attributes :id, :type, :actor, :to
 
   has_one :object, serializer: TombstoneSerializer
 
@@ -32,4 +32,8 @@ class ActivityPub::DeleteSerializer < ActiveModel::Serializer
   def actor
     ActivityPub::TagManager.instance.uri_for(object.account)
   end
+
+  def to
+    [ActivityPub::TagManager::COLLECTIONS[:public]]
+  end
 end
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index 82b7ffe95cb87ea97f0ea15da139d787fc0aec24..c9d23e25fa8543e6d594fdc3bd39f57bbac8dc6a 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -68,7 +68,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
   end
 
   def virtual_tags
-    object.mentions.to_a.sort_by(&:id) + object.tags + object.emojis
+    object.active_mentions.to_a.sort_by(&:id) + object.tags + object.emojis
   end
 
   def atom_uri
diff --git a/app/serializers/activitypub/undo_announce_serializer.rb b/app/serializers/activitypub/undo_announce_serializer.rb
index 839847e22c0ff183b7ffd2031155aa94e58de4ab..4fc042727ad6898aae581d824332ba6df3372421 100644
--- a/app/serializers/activitypub/undo_announce_serializer.rb
+++ b/app/serializers/activitypub/undo_announce_serializer.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
-  attributes :id, :type, :actor
+  attributes :id, :type, :actor, :to
 
   has_one :object, serializer: ActivityPub::ActivitySerializer
 
@@ -16,4 +16,8 @@ class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
   def actor
     ActivityPub::TagManager.instance.uri_for(object.account)
   end
+
+  def to
+    [ActivityPub::TagManager::COLLECTIONS[:public]]
+  end
 end
diff --git a/app/serializers/activitypub/update_serializer.rb b/app/serializers/activitypub/update_serializer.rb
index ebc667d9630d17e9252e84d9996b1d1f211d6c74..48d7a192946a70875e79fc5ee8f6d44e605674c4 100644
--- a/app/serializers/activitypub/update_serializer.rb
+++ b/app/serializers/activitypub/update_serializer.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class ActivityPub::UpdateSerializer < ActiveModel::Serializer
-  attributes :id, :type, :actor
+  attributes :id, :type, :actor, :to
 
   has_one :object, serializer: ActivityPub::ActorSerializer
 
@@ -16,4 +16,8 @@ class ActivityPub::UpdateSerializer < ActiveModel::Serializer
   def actor
     ActivityPub::TagManager.instance.uri_for(object)
   end
+
+  def to
+    [ActivityPub::TagManager::COLLECTIONS[:public]]
+  end
 end
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index 42d0e4bf324ae1b65916846e4bf18bcdb2bdbbac..a7a3d770ce6eb26b5e560251017d88bacde703ba 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -14,17 +14,22 @@ class InitialStateSerializer < ActiveModel::Serializer
       domain: Rails.configuration.x.local_domain,
       admin: object.admin&.id&.to_s,
       search_enabled: Chewy.enabled?,
+      version: Mastodon::Version.to_s,
       invites_enabled: Setting.min_invite_role == 'user',
+      mascot: instance_presenter.mascot&.file&.url,
+      profile_directory: Setting.profile_directory,
     }
 
     if object.current_account
-      store[:me]                      = object.current_account.id.to_s
-      store[:unfollow_modal]          = object.current_account.user.setting_unfollow_modal
-      store[:boost_modal]             = object.current_account.user.setting_boost_modal
-      store[:delete_modal]            = object.current_account.user.setting_delete_modal
-      store[:auto_play_gif]           = object.current_account.user.setting_auto_play_gif
-      store[:display_sensitive_media] = object.current_account.user.setting_display_sensitive_media
-      store[:reduce_motion]           = object.current_account.user.setting_reduce_motion
+      store[:me]              = object.current_account.id.to_s
+      store[:unfollow_modal]  = object.current_account.user.setting_unfollow_modal
+      store[:boost_modal]     = object.current_account.user.setting_boost_modal
+      store[:delete_modal]    = object.current_account.user.setting_delete_modal
+      store[:auto_play_gif]   = object.current_account.user.setting_auto_play_gif
+      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[:is_staff]        = object.current_account.user.staff?
     end
 
     store
@@ -54,4 +59,10 @@ class InitialStateSerializer < ActiveModel::Serializer
   def media_attachments
     { accept_content_types: MediaAttachment::IMAGE_FILE_EXTENSIONS + MediaAttachment::VIDEO_FILE_EXTENSIONS + MediaAttachment::IMAGE_MIME_TYPES + MediaAttachment::VIDEO_MIME_TYPES }
   end
+
+  private
+
+  def instance_presenter
+    @instance_presenter ||= InstancePresenter.new
+  end
 end
diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb
index 3a724aa7c271491bdb51cea5bb368a0f4ae56ac0..12adc971cb76a6894338b2dcf342d34026b287a3 100644
--- a/app/serializers/rest/account_serializer.rb
+++ b/app/serializers/rest/account_serializer.rb
@@ -11,7 +11,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
   has_many :emojis, serializer: REST::CustomEmojiSerializer
 
   class FieldSerializer < ActiveModel::Serializer
-    attributes :name, :value
+    attributes :name, :value, :verified_at
 
     def value
       Formatter.instance.format_field(object.account, object.value)
diff --git a/app/serializers/rest/conversation_serializer.rb b/app/serializers/rest/conversation_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b09ca63419f30383471f5da4b506893921ba04ec
--- /dev/null
+++ b/app/serializers/rest/conversation_serializer.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class REST::ConversationSerializer < ActiveModel::Serializer
+  attributes :id, :unread
+
+  has_many :participant_accounts, key: :accounts, serializer: REST::AccountSerializer
+  has_one :last_status, serializer: REST::StatusSerializer
+
+  def id
+    object.id.to_s
+  end
+end
diff --git a/app/serializers/rest/filter_serializer.rb b/app/serializers/rest/filter_serializer.rb
index 3134be371b066bc0c734f8bde72dea7b75115b27..57205630bbbf84fe8765807cd64471e148dc8918 100644
--- a/app/serializers/rest/filter_serializer.rb
+++ b/app/serializers/rest/filter_serializer.rb
@@ -3,4 +3,8 @@
 class REST::FilterSerializer < ActiveModel::Serializer
   attributes :id, :phrase, :context, :whole_word, :expires_at,
              :irreversible
+
+  def id
+    object.id.to_s
+  end
 end
diff --git a/app/serializers/rest/relationship_serializer.rb b/app/serializers/rest/relationship_serializer.rb
index 45bfd4d6e7635a1372ab84a5e03bd5db6b5d858a..c6c722a54ea0d30a5031c048a4230caa2be64890 100644
--- a/app/serializers/rest/relationship_serializer.rb
+++ b/app/serializers/rest/relationship_serializer.rb
@@ -2,7 +2,8 @@
 
 class REST::RelationshipSerializer < ActiveModel::Serializer
   attributes :id, :following, :showing_reblogs, :followed_by, :blocking,
-             :muting, :muting_notifications, :requested, :domain_blocking
+             :muting, :muting_notifications, :requested, :domain_blocking,
+             :endorsed
 
   def id
     object.id.to_s
@@ -41,4 +42,8 @@ class REST::RelationshipSerializer < ActiveModel::Serializer
   def domain_blocking
     instance_options[:relationships].domain_blocking[object.id] || false
   end
+
+  def endorsed
+    instance_options[:relationships].endorsed[object.id] || false
+  end
 end
diff --git a/app/serializers/rest/scheduled_status_serializer.rb b/app/serializers/rest/scheduled_status_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5d6311b872156310a50a9c888607b1b8aad99747
--- /dev/null
+++ b/app/serializers/rest/scheduled_status_serializer.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class REST::ScheduledStatusSerializer < ActiveModel::Serializer
+  attributes :id, :scheduled_at, :params
+
+  has_many :media_attachments, serializer: REST::MediaAttachmentSerializer
+
+  def id
+    object.id.to_s
+  end
+
+  def params
+    object.params.without(:application_id)
+  end
+end
diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb
index fe3dc9bfcfb2838d9bd1a75437f13d2cbe57e374..bfc2d78b41f8f1f9c87599d08f143417bbcde729 100644
--- a/app/serializers/rest/status_serializer.rb
+++ b/app/serializers/rest/status_serializer.rb
@@ -3,7 +3,8 @@
 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, :reblogs_count, :favourites_count
+             :uri, :content, :url, :replies_count, :reblogs_count,
+             :favourites_count
 
   attribute :favourited, if: :current_user?
   attribute :reblogged, if: :current_user?
@@ -19,6 +20,8 @@ class REST::StatusSerializer < ActiveModel::Serializer
   has_many :tags
   has_many :emojis, serializer: REST::CustomEmojiSerializer
 
+  has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
+
   def id
     object.id.to_s
   end
@@ -35,6 +38,17 @@ class REST::StatusSerializer < ActiveModel::Serializer
     !current_user.nil?
   end
 
+  def visibility
+    # This visibility is masked behind "private"
+    # to avoid API changes because there are no
+    # UX differences
+    if object.limited_visibility?
+      'private'
+    else
+      object.visibility
+    end
+  end
+
   def uri
     OStatus::TagManager.instance.uri_for(object)
   end
@@ -87,7 +101,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
   end
 
   def ordered_mentions
-    object.mentions.to_a.sort_by(&:id)
+    object.active_mentions.to_a.sort_by(&:id)
   end
 
   class ApplicationSerializer < ActiveModel::Serializer
diff --git a/app/serializers/web/notification_serializer.rb b/app/serializers/web/notification_serializer.rb
index 43ba4d92a26c2d86ad7429c080875cafa635fce2..ee83ec8b26e7e46376ca490be9f131a0af5b5f41 100644
--- a/app/serializers/web/notification_serializer.rb
+++ b/app/serializers/web/notification_serializer.rb
@@ -33,7 +33,7 @@ class Web::NotificationSerializer < ActiveModel::Serializer
   end
 
   def body
-    str = truncate(strip_tags(object.target_status&.spoiler_text&.presence || object.target_status&.text || object.from_account.note), length: 140)
-    HTMLEntities.new.decode(str.to_str) # Do not encode entities, since this value will not be used in HTML
+    str = strip_tags(object.target_status&.spoiler_text&.presence || object.target_status&.text || object.from_account.note)
+    truncate(HTMLEntities.new.decode(str.to_str), length: 140) # Do not encode entities, since this value will not be used in HTML
   end
 end
diff --git a/app/serializers/webfinger_serializer.rb b/app/serializers/webfinger_serializer.rb
index f80d12c024f099ce43b411e217017c6e1725e4b2..8c0b077020dcd2ce7833cf7063c8db3bf764bfb0 100644
--- a/app/serializers/webfinger_serializer.rb
+++ b/app/serializers/webfinger_serializer.rb
@@ -20,7 +20,7 @@ class WebfingerSerializer < ActiveModel::Serializer
       { rel: 'self', type: 'application/activity+json', href: account_url(object) },
       { rel: 'salmon', href: api_salmon_url(object.id) },
       { rel: 'magic-public-key', href: "data:application/magic-public-key,#{object.magic_key}" },
-      { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}" },
+      { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_interaction_url}?uri={uri}" },
     ]
   end
 end
diff --git a/app/services/activitypub/fetch_remote_account_service.rb b/app/services/activitypub/fetch_remote_account_service.rb
index 867e7087606fdeb3d4c9e415c373fc0cf865a54d..3c204494128ec10afe6da731ac1c196a37b699f5 100644
--- a/app/services/activitypub/fetch_remote_account_service.rb
+++ b/app/services/activitypub/fetch_remote_account_service.rb
@@ -5,24 +5,25 @@ class ActivityPub::FetchRemoteAccountService < BaseService
 
   SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
 
-  # Should be called when uri has already been checked for locality
-  # Does a WebFinger roundtrip on each call
-  def call(uri, id: true, prefetched_body: nil)
+  # Does a WebFinger roundtrip on each call, unless `only_key` is true
+  def call(uri, id: true, prefetched_body: nil, break_on_redirect: false, only_key: false)
+    return ActivityPub::TagManager.instance.uri_to_resource(uri, Account) if ActivityPub::TagManager.instance.local_uri?(uri)
+
     @json = if prefetched_body.nil?
               fetch_resource(uri, id)
             else
-              body_to_json(prefetched_body)
+              body_to_json(prefetched_body, compare_id: id ? uri : nil)
             end
 
-    return unless supported_context? && expected_type?
+    return if !supported_context? || !expected_type? || (break_on_redirect && @json['movedTo'].present?)
 
     @uri      = @json['id']
     @username = @json['preferredUsername']
     @domain   = Addressable::URI.parse(@uri).normalized_host
 
-    return unless verified_webfinger?
+    return unless only_key || verified_webfinger?
 
-    ActivityPub::ProcessAccountService.new.call(@username, @domain, @json)
+    ActivityPub::ProcessAccountService.new.call(@username, @domain, @json, only_key: only_key)
   rescue Oj::ParseError
     nil
   end
diff --git a/app/services/activitypub/fetch_remote_key_service.rb b/app/services/activitypub/fetch_remote_key_service.rb
index 505baccd46e2305e56a6b1d9c786040d0812d629..df17d907932740815745de361492678b736c0133 100644
--- a/app/services/activitypub/fetch_remote_key_service.rb
+++ b/app/services/activitypub/fetch_remote_key_service.rb
@@ -17,7 +17,7 @@ class ActivityPub::FetchRemoteKeyService < BaseService
         @json = fetch_resource(uri, id)
       end
     else
-      @json = body_to_json(prefetched_body)
+      @json = body_to_json(prefetched_body, compare_id: id ? uri : nil)
     end
 
     return unless supported_context?(@json) && expected_type?
diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb
index 2b447abb32eb5fa95771d9cb7424b138326f6125..469821032ab69746c12ea79b868f1e4b1626fa9c 100644
--- a/app/services/activitypub/fetch_remote_status_service.rb
+++ b/app/services/activitypub/fetch_remote_status_service.rb
@@ -8,7 +8,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService
     @json = if prefetched_body.nil?
               fetch_resource(uri, id, on_behalf_of)
             else
-              body_to_json(prefetched_body)
+              body_to_json(prefetched_body, compare_id: id ? uri : nil)
             end
 
     return unless supported_context? && expected_type?
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index 453253db40502a3341c2e23f671aa720fbccc62c..487456f3afcec2fec587d409a583310ed041d7b5 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -5,9 +5,10 @@ class ActivityPub::ProcessAccountService < BaseService
 
   # Should be called with confirmed valid JSON
   # and WebFinger-resolved username and domain
-  def call(username, domain, json)
+  def call(username, domain, json, options = {})
     return if json['inbox'].blank? || unsupported_uri_scheme?(json['id'])
 
+    @options     = options
     @json        = json
     @uri         = @json['id']
     @username    = username
@@ -31,8 +32,13 @@ class ActivityPub::ProcessAccountService < BaseService
     return if @account.nil?
 
     after_protocol_change! if protocol_changed?
-    after_key_change! if key_changed?
-    check_featured_collection! if @account.featured_collection_url.present?
+    after_key_change! if key_changed? && !@options[:signed_with_known_key]
+    clear_tombstones! if key_changed?
+
+    unless @options[:only_key]
+      check_featured_collection! if @account.featured_collection_url.present?
+      check_links! unless @account.fields.empty?
+    end
 
     @account
   rescue Oj::ParseError
@@ -52,11 +58,11 @@ class ActivityPub::ProcessAccountService < BaseService
   end
 
   def update_account
-    @account.last_webfingered_at = Time.now.utc
+    @account.last_webfingered_at = Time.now.utc unless @options[:only_key]
     @account.protocol            = :activitypub
 
     set_immediate_attributes!
-    set_fetchable_attributes!
+    set_fetchable_attributes! unless @options[:only_keys]
 
     @account.save_with_optional_media!
   end
@@ -73,6 +79,7 @@ class ActivityPub::ProcessAccountService < BaseService
     @account.note                    = @json['summary'] || ''
     @account.locked                  = @json['manuallyApprovesFollowers'] || false
     @account.fields                  = property_values || {}
+    @account.also_known_as           = as_array(@json['alsoKnownAs'] || []).map { |item| value_or_id(item) }
     @account.actor_type              = actor_type
   end
 
@@ -98,6 +105,10 @@ class ActivityPub::ProcessAccountService < BaseService
     ActivityPub::SynchronizeFeaturedCollectionWorker.perform_async(@account.id)
   end
 
+  def check_links!
+    VerifyAccountLinksWorker.perform_async(@account.id)
+  end
+
   def actor_type
     if @json['type'].is_a?(Array)
       @json['type'].find { |type| ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(type) }
@@ -175,7 +186,7 @@ class ActivityPub::ProcessAccountService < BaseService
 
   def moved_account
     account   = ActivityPub::TagManager.instance.uri_to_resource(@json['movedTo'], Account)
-    account ||= ActivityPub::FetchRemoteAccountService.new.call(@json['movedTo'], id: true)
+    account ||= ActivityPub::FetchRemoteAccountService.new.call(@json['movedTo'], id: true, break_on_redirect: true)
     account
   end
 
@@ -200,6 +211,10 @@ class ActivityPub::ProcessAccountService < BaseService
     !@old_public_key.nil? && @old_public_key != @account.public_key
   end
 
+  def clear_tombstones!
+    Tombstone.delete_all(account_id: @account.id)
+  end
+
   def protocol_changed?
     !@old_protocol.nil? && @old_protocol != @account.protocol
   end
@@ -226,7 +241,7 @@ class ActivityPub::ProcessAccountService < BaseService
     updated   = tag['updated']
     emoji     = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain)
 
-    return unless emoji.nil? || emoji.updated_at >= updated
+    return unless emoji.nil? || image_url != emoji.image_remote_url || (updated && updated >= emoji.updated_at)
 
     emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: shortcode, uri: uri)
     emoji.image_remote_url = image_url
diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb
index 79cdca297be0571589547d25984a479f48215b76..5c54aad89f18407d6c05d51481717296e066b8d1 100644
--- a/app/services/activitypub/process_collection_service.rb
+++ b/app/services/activitypub/process_collection_service.rb
@@ -27,7 +27,7 @@ class ActivityPub::ProcessCollectionService < BaseService
   private
 
   def different_actor?
-    @json['actor'].present? && value_or_id(@json['actor']) != @account.uri && @json['signature'].present?
+    @json['actor'].present? && value_or_id(@json['actor']) != @account.uri
   end
 
   def process_items(items)
diff --git a/app/services/after_block_domain_from_account_service.rb b/app/services/after_block_domain_from_account_service.rb
index 0f1a8505d31fe7f583cfe1c465f1b8708a9615ea..180f134032375f8af3d27c7a07d03f1a2471e91b 100644
--- a/app/services/after_block_domain_from_account_service.rb
+++ b/app/services/after_block_domain_from_account_service.rb
@@ -15,13 +15,13 @@ class AfterBlockDomainFromAccountService < BaseService
   private
 
   def reject_existing_followers!
-    @account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).find_each do |follow|
+    @account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).find_each do |follow|
       reject_follow!(follow)
     end
   end
 
   def reject_pending_follow_requests!
-    FollowRequest.where(target_account: @account).where(account: Account.where(domain: @domain)).includes(:account).find_each do |follow_request|
+    FollowRequest.where(target_account: @account).where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).find_each do |follow_request|
       reject_follow!(follow_request)
     end
   end
@@ -31,11 +31,11 @@ class AfterBlockDomainFromAccountService < BaseService
 
     return unless follow.account.activitypub?
 
-    json = Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
+    json = ActiveModelSerializers::SerializableResource.new(
       follow,
       serializer: ActivityPub::RejectFollowSerializer,
       adapter: ActivityPub::Adapter
-    ).as_json).sign!(@account))
+    ).to_json
 
     ActivityPub::DeliveryWorker.perform_async(json, @account.id, follow.account.inbox_url)
   end
diff --git a/app/services/after_block_service.rb b/app/services/after_block_service.rb
index a7dce08c75898dcffa8a2bfbe35cf6b3e2af35fc..706db0d6334d9a82fbbc52bcc90ef7fb7f4050f5 100644
--- a/app/services/after_block_service.rb
+++ b/app/services/after_block_service.rb
@@ -2,16 +2,43 @@
 
 class AfterBlockService < BaseService
   def call(account, target_account)
-    FeedManager.instance.clear_from_timeline(account, target_account)
+    clear_home_feed(account, target_account)
     clear_notifications(account, target_account)
+    clear_conversations(account, target_account)
   end
 
   private
 
+  def clear_home_feed(account, target_account)
+    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
+  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
+    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
   end
 end
diff --git a/app/services/app_sign_up_service.rb b/app/services/app_sign_up_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d621cc462c6460af70157690c1524cb42a0f2735
--- /dev/null
+++ b/app/services/app_sign_up_service.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class AppSignUpService < BaseService
+  def call(app, params)
+    return unless allowed_registrations?
+
+    user_params    = params.slice(:email, :password, :agreement, :locale)
+    account_params = params.slice(:username)
+    user           = User.create!(user_params.merge(created_by_application: app, password_confirmation: user_params[:password], account_attributes: account_params))
+
+    Doorkeeper::AccessToken.create!(application: app,
+                                    resource_owner_id: user.id,
+                                    scopes: app.scopes,
+                                    expires_in: Doorkeeper.configuration.access_token_expires_in,
+                                    use_refresh_token: Doorkeeper.configuration.refresh_token_enabled?)
+  end
+
+  private
+
+  def allowed_registrations?
+    Setting.open_registrations && !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 f47d488f11c6db297aab466b2f5fe388ace95425..f2e3ebe7d00b4770fea3dd2e478dfead17ee0027 100644
--- a/app/services/authorize_follow_service.rb
+++ b/app/services/authorize_follow_service.rb
@@ -3,7 +3,7 @@
 class AuthorizeFollowService < BaseService
   def call(source_account, target_account, **options)
     if options[:skip_follow_request]
-      follow_request = FollowRequest.new(account: source_account, target_account: target_account)
+      follow_request = FollowRequest.new(account: source_account, target_account: target_account, uri: options[:follow_request_uri])
     else
       follow_request = FollowRequest.find_by!(account: source_account, target_account: target_account)
       follow_request.authorize!
@@ -24,11 +24,11 @@ class AuthorizeFollowService < BaseService
   end
 
   def build_json(follow_request)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
+    ActiveModelSerializers::SerializableResource.new(
       follow_request,
       serializer: ActivityPub::AcceptFollowSerializer,
       adapter: ActivityPub::Adapter
-    ).as_json).sign!(follow_request.target_account))
+    ).to_json
   end
 
   def build_xml(follow_request)
diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb
index 8492c11176364d49ff87e6af12059cc75fcbcb40..4cfa22ab893604277313a921bc1c208de4092c2f 100644
--- a/app/services/backup_service.rb
+++ b/app/services/backup_service.rb
@@ -18,7 +18,7 @@ class BackupService < BaseService
   def build_json!
     @collection = serialize(collection_presenter, ActivityPub::CollectionSerializer)
 
-    account.statuses.with_includes.find_in_batches do |statuses|
+    account.statuses.with_includes.reorder(nil).find_in_batches do |statuses|
       statuses.each do |status|
         item = serialize(status, ActivityPub::ActivitySerializer)
         item.delete(:'@context')
@@ -44,6 +44,7 @@ class BackupService < BaseService
         Gem::Package::TarWriter.new(gz) do |tar|
           dump_media_attachments!(tar)
           dump_outbox!(tar)
+          dump_likes!(tar)
           dump_actor!(tar)
         end
       end
@@ -60,7 +61,7 @@ class BackupService < BaseService
   end
 
   def dump_media_attachments!(tar)
-    MediaAttachment.attached.where(account: account).find_in_batches do |media_attachments|
+    MediaAttachment.attached.where(account: account).reorder(nil).find_in_batches do |media_attachments|
       media_attachments.each do |m|
         download_to_tar(tar, m.file, m.file.path)
       end
@@ -82,6 +83,8 @@ class BackupService < BaseService
 
     actor[:icon][:url]  = 'avatar' + File.extname(actor[:icon][:url])  if actor[:icon]
     actor[:image][:url] = 'header' + File.extname(actor[:image][:url]) if actor[:image]
+    actor[:outbox]      = 'outbox.json'
+    actor[:likes]       = 'likes.json'
 
     download_to_tar(tar, account.avatar, 'avatar' + File.extname(account.avatar.path)) if account.avatar.exists?
     download_to_tar(tar, account.header, 'header' + File.extname(account.header.path)) if account.header.exists?
@@ -91,15 +94,30 @@ class BackupService < BaseService
     tar.add_file_simple('actor.json', 0o444, json.bytesize) do |io|
       io.write(json)
     end
+  end
+
+  def dump_likes!(tar)
+    collection = serialize(ActivityPub::CollectionPresenter.new(id: 'likes.json', type: :ordered, size: 0, items: []), ActivityPub::CollectionSerializer)
+
+    Status.reorder(nil).joins(:favourites).includes(:account).merge(account.favourites).find_in_batches do |statuses|
+      statuses.each do |status|
+        collection[:totalItems] += 1
+        collection[:orderedItems] << ActivityPub::TagManager.instance.uri_for(status)
+      end
 
-    tar.add_file_simple('key.pem', 0o444, account.private_key.bytesize) do |io|
-      io.write(account.private_key)
+      GC.start
+    end
+
+    json = Oj.dump(collection)
+
+    tar.add_file_simple('likes.json', 0o444, json.bytesize) do |io|
+      io.write(json)
     end
   end
 
   def collection_presenter
     ActivityPub::CollectionPresenter.new(
-      id: account_outbox_url(account),
+      id: 'outbox.json',
       type: :ordered,
       size: account.statuses_count,
       items: []
diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb
index ebb4034aaf13353bb268b7c67b0619018cc995f0..2e61904fc770f6f4011c784fb7dafe77bf502514 100644
--- a/app/services/batched_remove_status_service.rb
+++ b/app/services/batched_remove_status_service.rb
@@ -9,15 +9,17 @@ class BatchedRemoveStatusService < BaseService
   # Remove statuses from home feeds
   # Push delete events to streaming API for home feeds and public feeds
   # @param [Status] statuses A preferably batched array of statuses
-  def call(statuses)
+  # @param [Hash] options
+  # @option [Boolean] :skip_side_effects
+  def call(statuses, **options)
     statuses = Status.where(id: statuses.map(&:id)).includes(:account, :stream_entry).flat_map { |status| [status] + status.reblogs.includes(:account, :stream_entry).to_a }
 
-    @mentions = statuses.map { |s| [s.id, s.mentions.includes(:account).to_a] }.to_h
-    @tags     = statuses.map { |s| [s.id, s.tags.pluck(:name)] }.to_h
+    @mentions = statuses.each_with_object({}) { |s, h| h[s.id] = s.active_mentions.includes(:account).to_a }
+    @tags     = statuses.each_with_object({}) { |s, h| h[s.id] = s.tags.pluck(:name) }
 
     @stream_entry_batches  = []
     @salmon_batches        = []
-    @json_payloads         = statuses.map { |s| [s.id, Oj.dump(event: :delete, payload: s.id.to_s)] }.to_h
+    @json_payloads         = statuses.each_with_object({}) { |s, h| h[s.id] = Oj.dump(event: :delete, payload: s.id.to_s) }
     @activity_xml          = {}
 
     # Ensure that rendered XML reflects destroyed state
@@ -26,6 +28,8 @@ class BatchedRemoveStatusService < BaseService
       status.destroy
     end
 
+    return if options[:skip_side_effects]
+
     # Batch by source account
     statuses.group_by(&:account_id).each_value do |account_statuses|
       account = account_statuses.first.account
@@ -39,7 +43,6 @@ class BatchedRemoveStatusService < BaseService
     # Cannot be batched
     statuses.each do |status|
       unpush_from_public_timelines(status)
-      unpush_from_direct_timelines(status) if status.direct_visibility?
       batch_salmon_slaps(status) if status.local?
     end
 
@@ -96,16 +99,6 @@ class BatchedRemoveStatusService < BaseService
     end
   end
 
-  def unpush_from_direct_timelines(status)
-    payload = @json_payloads[status.id]
-    redis.pipelined do
-      @mentions[status.id].each do |mention|
-        redis.publish("timeline:direct:#{mention.account.id}", payload) if mention.account.local?
-      end
-      redis.publish("timeline:direct:#{status.account.id}", payload) if status.account.local?
-    end
-  end
-
   def batch_salmon_slaps(status)
     return if @mentions[status.id].empty?
 
diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb
index d082de40b9b45057b5ae7e416c6d0b078e5f2a20..a1fe93665b117b7df8051fe88c0d177d302a2714 100644
--- a/app/services/block_domain_service.rb
+++ b/app/services/block_domain_service.rb
@@ -43,14 +43,14 @@ class BlockDomainService < BaseService
   end
 
   def suspend_accounts!
-    blocked_domain_accounts.where(suspended: false).find_each do |account|
+    blocked_domain_accounts.where(suspended: false).reorder(nil).find_each do |account|
       UnsubscribeService.new.call(account) if account.subscribed?
       SuspendAccountService.new.call(account)
     end
   end
 
   def clear_account_images!
-    blocked_domain_accounts.find_each do |account|
+    blocked_domain_accounts.reorder(nil).find_each do |account|
       account.avatar.destroy if account.avatar.exists?
       account.header.destroy if account.header.exists?
       account.save
@@ -58,7 +58,7 @@ class BlockDomainService < BaseService
   end
 
   def clear_account_attachments!
-    media_from_blocked_domain.find_each do |attachment|
+    media_from_blocked_domain.reorder(nil).find_each do |attachment|
       @affected_status_ids << attachment.status_id if attachment.status_id.present?
 
       attachment.file.destroy if attachment.file.exists?
diff --git a/app/services/block_service.rb b/app/services/block_service.rb
index b39c3eef2869b57087bbd09af80aff0f060efc70..140b238df3e418dcab536a1506fa021cd9aac094 100644
--- a/app/services/block_service.rb
+++ b/app/services/block_service.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 class BlockService < BaseService
-  include StreamEntryRenderer
-
   def call(account, target_account)
     return if account.id == target_account.id
 
@@ -27,11 +25,11 @@ class BlockService < BaseService
   end
 
   def build_json(block)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
+    ActiveModelSerializers::SerializableResource.new(
       block,
       serializer: ActivityPub::BlockSerializer,
       adapter: ActivityPub::Adapter
-    ).as_json).sign!(block.account))
+    ).to_json
   end
 
   def build_xml(block)
diff --git a/app/services/concerns/author_extractor.rb b/app/services/concerns/author_extractor.rb
index 1e00eb803b73a00c517e96b48c44d9f8d22ceeb2..c2419e9ecb23d6520897848a6bcd4396d87246de 100644
--- a/app/services/concerns/author_extractor.rb
+++ b/app/services/concerns/author_extractor.rb
@@ -18,6 +18,6 @@ module AuthorExtractor
       acct   = "#{username}@#{domain}"
     end
 
-    ResolveAccountService.new.call(acct, update_profile)
+    ResolveAccountService.new.call(acct, update_profile: update_profile)
   end
 end
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index 5efd3edb2e428b3cfc650f540a194d0711cc2afe..f3e9c855dc55441652a6e9cdf2fa3f3773c78b72 100644
--- a/app/services/fan_out_on_write_service.rb
+++ b/app/services/fan_out_on_write_service.rb
@@ -6,14 +6,14 @@ class FanOutOnWriteService < BaseService
   def call(status)
     raise Mastodon::RaceConditionError if status.visibility.nil?
 
-    deliver_to_self(status) if status.account.local?
-
     render_anonymous_payload(status)
 
     if status.direct_visibility?
+      deliver_to_own_conversation(status)
+    elsif status.limited_visibility?
       deliver_to_mentioned_followers(status)
-      deliver_to_direct_timelines(status)
     else
+      deliver_to_self(status) if status.account.local?
       deliver_to_followers(status)
       deliver_to_lists(status)
     end
@@ -56,12 +56,10 @@ class FanOutOnWriteService < BaseService
   end
 
   def deliver_to_mentioned_followers(status)
-    Rails.logger.debug "Delivering status #{status.id} to mentioned followers"
+    Rails.logger.debug "Delivering status #{status.id} to limited followers"
 
-    status.mentions.includes(:account).each do |mention|
-      mentioned_account = mention.account
-      next if !mentioned_account.local? || !mentioned_account.following?(status.account) || FeedManager.instance.filter?(:home, status, mention.account_id)
-      FeedManager.instance.push_to_home(mentioned_account, status)
+    FeedInsertWorker.push_bulk(status.mentions.includes(:account).map(&:account).select { |mentioned_account| mentioned_account.local? && mentioned_account.following?(status.account) }) do |follower|
+      [status.id, follower.id, :home]
     end
   end
 
@@ -93,12 +91,7 @@ class FanOutOnWriteService < BaseService
     Redis.current.publish('timeline:public:local:media', @payload) if status.local?
   end
 
-  def deliver_to_direct_timelines(status)
-    Rails.logger.debug "Delivering status #{status.id} to direct timelines"
-
-    status.mentions.includes(:account).each do |mention|
-      Redis.current.publish("timeline:direct:#{mention.account.id}", @payload) if mention.account.local?
-    end
-    Redis.current.publish("timeline:direct:#{status.account.id}", @payload) if status.account.local?
+  def deliver_to_own_conversation(status)
+    AccountConversation.add_status(status.account, status)
   end
 end
diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb
index 6e1ac3ba99b046c97891bac152cd76e8f5fda495..b565bcc3203f30c9f2544c0fccbab496d7fddf7c 100644
--- a/app/services/favourite_service.rb
+++ b/app/services/favourite_service.rb
@@ -37,6 +37,7 @@ class FavouriteService < BaseService
   end
 
   def bump_potential_friendship(account, status)
+    ActivityTracker.increment('activity:interactions')
     return if account.following?(status.account_id)
     PotentialFriendshipTracker.record(account.id, status.account_id, :favourite)
   end
diff --git a/app/services/fetch_atom_service.rb b/app/services/fetch_atom_service.rb
index 550e75f3344b174cd11612707e284c3f5a7274ac..d6508a9888a69fad1b695a3cd59a4cb971120cac 100644
--- a/app/services/fetch_atom_service.rb
+++ b/app/services/fetch_atom_service.rb
@@ -29,7 +29,7 @@ class FetchAtomService < BaseService
 
   def perform_request(&block)
     accept = 'text/html'
-    accept = 'application/activity+json, application/ld+json, application/atom+xml, ' + accept unless @unsupported_activity
+    accept = 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams", application/atom+xml, ' + accept unless @unsupported_activity
 
     Request.new(:get, @url).add_headers('Accept' => accept).perform(&block)
   end
@@ -39,7 +39,7 @@ class FetchAtomService < BaseService
 
     if response.mime_type == 'application/atom+xml'
       [@url, { prefetched_body: response.body_with_limit }, :ostatus]
-    elsif ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(response.mime_type)
+    elsif ['application/activity+json', 'application/ld+json'].include?(response.mime_type)
       body = response.body_with_limit
       json = body_to_json(body)
       if supported_context?(json) && equals_or_includes_any?(json['type'], ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES) && json['inbox'].present?
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index 560a8176877a6a6a1388016a27bc28d101977a96..7979c312e5d771c84efbca492e495c4e54ccb019 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -29,7 +29,7 @@ class FetchLinkCardService < BaseService
     end
 
     attach_card if @card&.persisted?
-  rescue HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::LengthValidationError => e
+  rescue HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e
     Rails.logger.debug "Error fetching link #{@url}: #{e}"
     nil
   end
@@ -62,6 +62,7 @@ class FetchLinkCardService < BaseService
 
   def attach_card
     @status.preview_cards << @card
+    Rails.cache.delete(@status)
   end
 
   def parse_urls
@@ -81,40 +82,48 @@ class FetchLinkCardService < BaseService
     uri.host.blank? || TagManager.instance.local_url?(uri.to_s) || !%w(http https).include?(uri.scheme)
   end
 
+  def mention_link?(a)
+    @status.mentions.any? do |mention|
+      a['href'] == TagManager.instance.url_for(mention.account)
+    end
+  end
+
   def skip_link?(a)
     # Avoid links for hashtags and mentions (microformats)
-    a['rel']&.include?('tag') || a['class']&.include?('u-url')
+    a['rel']&.include?('tag') || a['class']&.include?('u-url') || mention_link?(a)
   end
 
   def attempt_oembed
-    embed = FetchOEmbedService.new.call(@url, html: @html)
+    service = FetchOEmbedService.new
+    embed   = service.call(@url, html: @html)
+    url     = Addressable::URI.parse(service.endpoint_url)
 
     return false if embed.nil?
 
     @card.type          = embed[:type]
     @card.title         = embed[:title]         || ''
     @card.author_name   = embed[:author_name]   || ''
-    @card.author_url    = embed[:author_url]    || ''
+    @card.author_url    = embed[:author_url].present? ? (url + embed[:author_url]).to_s : ''
     @card.provider_name = embed[:provider_name] || ''
-    @card.provider_url  = embed[:provider_url]  || ''
+    @card.provider_url  = embed[:provider_url].present? ? (url + embed[:provider_url]).to_s : ''
     @card.width         = 0
     @card.height        = 0
 
     case @card.type
     when 'link'
-      @card.image_remote_url = embed[:thumbnail_url] if embed[:thumbnail_url].present?
+      @card.image_remote_url = (url + embed[:thumbnail_url]).to_s if embed[:thumbnail_url].present?
     when 'photo'
       return false if embed[:url].blank?
 
-      @card.embed_url        = embed[:url]
-      @card.image_remote_url = embed[:url]
+      @card.embed_url        = (url + embed[:url]).to_s
+      @card.image_remote_url = (url + embed[:url]).to_s
       @card.width            = embed[:width].presence  || 0
       @card.height           = embed[:height].presence || 0
     when 'video'
       @card.width            = embed[:width].presence  || 0
       @card.height           = embed[:height].presence || 0
       @card.html             = Formatter.instance.sanitize(embed[:html], Sanitize::Config::MASTODON_OEMBED)
-      @card.image_remote_url = embed[:thumbnail_url] if embed[:thumbnail_url].present?
+      @card.image_remote_url = (url + embed[:thumbnail_url]).to_s if embed[:thumbnail_url].present?
     when 'rich'
       # Most providers rely on <script> tags, which is a no-no
       return false
@@ -127,14 +136,16 @@ class FetchLinkCardService < BaseService
     detector = CharlockHolmes::EncodingDetector.new
     detector.strip_tags = true
 
-    guess = detector.detect(@html, @html_charset)
-    page  = Nokogiri::HTML(@html, nil, guess&.fetch(:encoding, nil))
+    guess      = detector.detect(@html, @html_charset)
+    encoding   = guess&.fetch(:confidence, 0).to_i > 60 ? guess&.fetch(:encoding, nil) : nil
+    page       = Nokogiri::HTML(@html, nil, encoding)
+    player_url = meta_property(page, 'twitter:player')
 
-    if meta_property(page, 'twitter:player')
+    if player_url && !bad_url?(Addressable::URI.parse(player_url))
       @card.type   = :video
       @card.width  = meta_property(page, 'twitter:player:width') || 0
       @card.height = meta_property(page, 'twitter:player:height') || 0
-      @card.html   = content_tag(:iframe, nil, src: meta_property(page, 'twitter:player'),
+      @card.html   = content_tag(:iframe, nil, src: player_url,
                                                width: @card.width,
                                                height: @card.height,
                                                allowtransparency: 'true',
@@ -146,7 +157,7 @@ class FetchLinkCardService < BaseService
 
     @card.title            = meta_property(page, 'og:title').presence || page.at_xpath('//title')&.content || ''
     @card.description      = meta_property(page, 'og:description').presence || meta_property(page, 'description') || ''
-    @card.image_remote_url = meta_property(page, 'og:image') if meta_property(page, 'og:image')
+    @card.image_remote_url = (Addressable::URI.parse(@url) + meta_property(page, 'og:image')).to_s if meta_property(page, 'og:image')
 
     return if @card.title.blank? && @card.html.blank?
 
diff --git a/app/services/fetch_oembed_service.rb b/app/services/fetch_oembed_service.rb
index 9982285171b287fbe1f23d4bb5c6a5de2500f15e..10176cfb99466bef0f56dd29fe521f1c2f606a6a 100644
--- a/app/services/fetch_oembed_service.rb
+++ b/app/services/fetch_oembed_service.rb
@@ -31,7 +31,7 @@ class FetchOEmbedService
 
     return if @endpoint_url.blank?
 
-    @endpoint_url = Addressable::URI.parse(@endpoint_url).to_s
+    @endpoint_url = (Addressable::URI.parse(@url) + @endpoint_url).to_s
   rescue Addressable::URI::InvalidURIError
     @endpoint_url = nil
   end
@@ -43,7 +43,7 @@ class FetchOEmbedService
       res.code != 200 ? nil : res.body_with_limit
     end
 
-    validate(parse_for_format(body)) unless body.nil?
+    validate(parse_for_format(body)) if body.present?
   rescue Oj::ParseError, Ox::ParseError
     nil
   end
diff --git a/app/services/fetch_remote_account_service.rb b/app/services/fetch_remote_account_service.rb
index a0f031a4450651dd860200eb4ad8b0871c38dc72..cfc560022fe6d6f7aae8fb122c798aab0bb4dde3 100644
--- a/app/services/fetch_remote_account_service.rb
+++ b/app/services/fetch_remote_account_service.rb
@@ -27,7 +27,7 @@ class FetchRemoteAccountService < BaseService
 
     account = author_from_xml(xml.at_xpath('/xmlns:feed', xmlns: OStatus::TagManager::XMLNS), false)
 
-    UpdateRemoteProfileService.new.call(xml, account) unless account.nil?
+    UpdateRemoteProfileService.new.call(xml, account) if account.present? && trusted_domain?(url, account)
 
     account
   rescue TypeError
@@ -37,4 +37,9 @@ class FetchRemoteAccountService < BaseService
     Rails.logger.debug 'Invalid XML or missing namespace'
     nil
   end
+
+  def trusted_domain?(url, account)
+    domain = Addressable::URI.parse(url).normalized_host
+    domain.casecmp(account.domain).zero? || domain.casecmp(Addressable::URI.parse(account.remote_url.presence || account.uri).normalized_host).zero?
+  end
 end
diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb
index 60a389afd34ed9b4099cf1f6f6c6571b7e6633ab..9d36a1449dff3721b028d0400d71b85848c141c5 100644
--- a/app/services/follow_service.rb
+++ b/app/services/follow_service.rb
@@ -1,18 +1,16 @@
 # frozen_string_literal: true
 
 class FollowService < BaseService
-  include StreamEntryRenderer
-
   # 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)
   # @param [true, false, nil] reblogs Whether or not to show reblogs, defaults to true
-  def call(source_account, uri, reblogs: nil)
+  def call(source_account, target_account, reblogs: nil)
     reblogs = true if reblogs.nil?
-    target_account = uri.is_a?(Account) ? uri : ResolveAccountService.new.call(uri)
+    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)
+    raise Mastodon::NotPermittedError  if target_account.blocking?(source_account) || source_account.blocking?(target_account) || target_account.moved?
 
     if source_account.following?(target_account)
       # We're already following this account, but we'll call follow! again to
@@ -27,6 +25,8 @@ class FollowService < BaseService
       return
     end
 
+    ActivityTracker.increment('activity:interactions')
+
     if target_account.locked? || target_account.activitypub?
       request_follow(source_account, target_account, reblogs: reblogs)
     else
@@ -40,7 +40,7 @@ class FollowService < BaseService
     follow_request = FollowRequest.create!(account: source_account, target_account: target_account, show_reblogs: reblogs)
 
     if target_account.local?
-      NotifyService.new.call(target_account, follow_request)
+      LocalNotificationWorker.perform_async(target_account.id, follow_request.id, follow_request.class.name)
     elsif target_account.ostatus?
       NotificationWorker.perform_async(build_follow_request_xml(follow_request), source_account.id, target_account.id)
       AfterRemoteFollowRequestWorker.perform_async(follow_request.id)
@@ -55,7 +55,7 @@ class FollowService < BaseService
     follow = source_account.follow!(target_account, reblogs: reblogs)
 
     if target_account.local?
-      NotifyService.new.call(target_account, follow)
+      LocalNotificationWorker.perform_async(target_account.id, follow.id, follow.class.name)
     else
       Pubsubhubbub::SubscribeWorker.perform_async(target_account.id) unless target_account.subscribed?
       NotificationWorker.perform_async(build_follow_xml(follow), source_account.id, target_account.id)
@@ -80,10 +80,10 @@ class FollowService < BaseService
   end
 
   def build_json(follow_request)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
+    ActiveModelSerializers::SerializableResource.new(
       follow_request,
       serializer: ActivityPub::FollowSerializer,
       adapter: ActivityPub::Adapter
-    ).as_json).sign!(follow_request.account))
+    ).to_json
   end
 end
diff --git a/app/services/hashtag_query_service.rb b/app/services/hashtag_query_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5773d78c6e2d2a38275558dce58b59878d59b001
--- /dev/null
+++ b/app/services/hashtag_query_service.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class HashtagQueryService < BaseService
+  def call(tag, params, account = nil, local = false)
+    tags = tags_for(Array(tag.name) | Array(params[:any])).pluck(:id)
+    all  = tags_for(params[:all])
+    none = tags_for(params[:none])
+
+    Status.distinct
+          .as_tag_timeline(tags, account, local)
+          .tagged_with_all(all)
+          .tagged_with_none(none)
+  end
+
+  private
+
+  def tags_for(tags)
+    Tag.where(name: tags.map(&:downcase)) if tags.presence
+  end
+end
diff --git a/app/services/mute_service.rb b/app/services/mute_service.rb
index c6122a152c0bf2c8e65e6005b60e9a1f3d59c760..676804cb991d97fa718f9b5554c47ea339daf4da 100644
--- a/app/services/mute_service.rb
+++ b/app/services/mute_service.rb
@@ -5,11 +5,13 @@ class MuteService < BaseService
     return if account.id == target_account.id
 
     mute = account.mute!(target_account, notifications: notifications)
+
     if mute.hide_notifications?
       BlockWorker.perform_async(account.id, target_account.id)
     else
-      FeedManager.instance.clear_from_timeline(account, target_account)
+      MuteWorker.perform_async(account.id, target_account.id)
     end
+
     mute
   end
 end
diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb
index 6490d2735bc14e8d2cb1fd11444a2ea645852fcf..b80ceef03c2428270ee14a29aebc28773a8938d3 100644
--- a/app/services/notify_service.rb
+++ b/app/services/notify_service.rb
@@ -8,9 +8,10 @@ class NotifyService < BaseService
 
     return if recipient.user.nil? || blocked?
 
-    create_notification
-    push_notification if @notification.browserable?
-    send_email if email_enabled?
+    create_notification!
+    push_notification! if @notification.browserable?
+    push_to_conversation! if direct_message?
+    send_email! if email_enabled?
   rescue ActiveRecord::RecordInvalid
     return
   end
@@ -30,7 +31,7 @@ class NotifyService < BaseService
   end
 
   def blocked_reblog?
-    @recipient.muting_reblogs?(@notification.from_account)
+    false
   end
 
   def blocked_follow_request?
@@ -50,14 +51,22 @@ class NotifyService < BaseService
     @recipient.user.settings.interactions['must_be_following'] && !following_sender?
   end
 
+  def message?
+    @notification.type == :mention
+  end
+
   def direct_message?
-    @notification.type == :mention && @notification.target_status.direct_visibility?
+    message? && @notification.target_status.direct_visibility?
   end
 
   def response_to_recipient?
     @notification.target_status.in_reply_to_account_id == @recipient.id && @notification.target_status.thread&.direct_visibility?
   end
 
+  def from_staff?
+    @notification.from_account.local? && @notification.from_account.user.present? && @notification.from_account.user.staff?
+  end
+
   def optional_non_following_and_direct?
     direct_message? &&
       @recipient.user.settings.interactions['must_be_following_dm'] &&
@@ -80,6 +89,9 @@ class NotifyService < BaseService
   def blocked?
     blocked   = @recipient.suspended?                            # Skip if the recipient account is suspended anyway
     blocked ||= from_self?                                       # Skip for interactions with self
+
+    return blocked if message? && from_staff?
+
     blocked ||= domain_blocking?                                 # Skip for domain blocked accounts
     blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts
     blocked ||= @recipient.muting_notifications?(@notification.from_account)
@@ -100,18 +112,23 @@ class NotifyService < BaseService
     end
   end
 
-  def create_notification
+  def create_notification!
     @notification.save!
   end
 
-  def push_notification
+  def push_notification!
     return if @notification.activity.nil?
 
     Redis.current.publish("timeline:#{@recipient.id}", Oj.dump(event: :notification, payload: InlineRenderer.render(@notification, @recipient, :notification)))
-    send_push_notifications
+    send_push_notifications!
+  end
+
+  def push_to_conversation!
+    return if @notification.activity.nil?
+    AccountConversation.add_status(@recipient, @notification.target_status)
   end
 
-  def send_push_notifications
+  def send_push_notifications!
     subscriptions_ids = ::Web::PushSubscription.where(user_id: @recipient.user.id)
                                                .select { |subscription| subscription.pushable?(@notification) }
                                                .map(&:id)
@@ -121,9 +138,9 @@ class NotifyService < BaseService
     end
   end
 
-  def send_email
+  def send_email!
     return if @notification.activity.nil?
-    NotificationMailer.public_send(@notification.type, @recipient, @notification).deliver_later
+    NotificationMailer.public_send(@notification.type, @recipient, @notification).deliver_later(wait: 2.minutes)
   end
 
   def email_enabled?
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 4c3485853dd5a57eec218e799e3205b73a583486..cc3453f995a1722cc9cd2dcfea2889b64f0de65c 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -1,69 +1,98 @@
 # frozen_string_literal: true
 
 class PostStatusService < BaseService
+  MIN_SCHEDULE_OFFSET = 5.minutes.freeze
+
   # Post a text status update, fetch and notify remote users mentioned
   # @param [Account] account Account from which to post
-  # @param [String] text Message
-  # @param [Status] in_reply_to Optional status to reply to
   # @param [Hash] options
+  # @option [String] :text Message
+  # @option [Status] :thread Optional status to reply to
   # @option [Boolean] :sensitive
   # @option [String] :visibility
   # @option [String] :spoiler_text
+  # @option [String] :language
+  # @option [String] :scheduled_at
   # @option [Enumerable] :media_ids Optional array of media IDs to attach
   # @option [Doorkeeper::Application] :application
   # @option [String] :idempotency Optional idempotency key
   # @return [Status]
-  def call(account, text, in_reply_to = nil, **options)
-    if options[:idempotency].present?
-      existing_id = redis.get("idempotency:status:#{account.id}:#{options[:idempotency]}")
-      return Status.find(existing_id) if existing_id
+  def call(account, options = {})
+    @account     = account
+    @options     = options
+    @text        = @options[:text] || ''
+    @in_reply_to = @options[:thread]
+
+    return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
+
+    validate_media!
+    preprocess_attributes!
+
+    if scheduled?
+      schedule_status!
+    else
+      process_status!
+      postprocess_status!
+      bump_potential_friendship!
     end
 
-    media  = validate_media!(options[:media_ids])
-    status = nil
-    text   = options.delete(:spoiler_text) if text.blank? && options[:spoiler_text].present?
+    redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
 
-    ApplicationRecord.transaction do
-      status = account.statuses.create!(text: text,
-                                        media_attachments: media || [],
-                                        thread: in_reply_to,
-                                        sensitive: (options[:sensitive].nil? ? account.user&.setting_default_sensitive : options[:sensitive]) || options[:spoiler_text].present?,
-                                        spoiler_text: options[:spoiler_text] || '',
-                                        visibility: options[:visibility] || account.user&.setting_default_privacy,
-                                        language: language_from_option(options[:language]) || account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(text, account),
-                                        application: options[:application])
-    end
+    @status
+  end
 
-    process_hashtags_service.call(status)
-    process_mentions_service.call(status)
+  private
 
-    LinkCrawlWorker.perform_async(status.id) unless status.spoiler_text?
-    DistributionWorker.perform_async(status.id)
-    Pubsubhubbub::DistributionWorker.perform_async(status.stream_entry.id)
-    ActivityPub::DistributionWorker.perform_async(status.id)
-    ActivityPub::ReplyDistributionWorker.perform_async(status.id) if status.reply? && status.thread.account.local?
+  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
+    @scheduled_at = @options[:scheduled_at]&.to_datetime
+    @scheduled_at = nil if scheduled_in_the_past?
+  rescue ArgumentError
+    raise ActiveRecord::RecordInvalid
+  end
 
-    if options[:idempotency].present?
-      redis.setex("idempotency:status:#{account.id}:#{options[:idempotency]}", 3_600, status.id)
-    end
+  def process_status!
+    # The following transaction block is needed to wrap the UPDATEs to
+    # the media attachments when the status is created
 
-    bump_potential_friendship(account, status)
+    ApplicationRecord.transaction do
+      @status = @account.statuses.create!(status_attributes)
+    end
 
-    status
+    process_hashtags_service.call(@status)
+    process_mentions_service.call(@status)
   end
 
-  private
+  def schedule_status!
+    if @account.statuses.build(status_attributes).valid?
+      # The following transaction block is needed to wrap the UPDATEs to
+      # the media attachments when the scheduled status is created
+
+      ApplicationRecord.transaction do
+        @status = @account.scheduled_statuses.create!(scheduled_status_attributes)
+      end
+    else
+      raise ActiveRecord::RecordInvalid
+    end
+  end
 
-  def validate_media!(media_ids)
-    return if media_ids.blank? || !media_ids.is_a?(Enumerable)
+  def postprocess_status!
+    LinkCrawlWorker.perform_async(@status.id) unless @status.spoiler_text?
+    DistributionWorker.perform_async(@status.id)
+    Pubsubhubbub::DistributionWorker.perform_async(@status.stream_entry.id)
+    ActivityPub::DistributionWorker.perform_async(@status.id)
+  end
 
-    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if media_ids.size > 4
+  def validate_media!
+    return if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
 
-    media = MediaAttachment.where(status_id: nil).where(id: media_ids.take(4).map(&:to_i))
+    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4
 
-    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if media.size > 1 && media.find(&:video?)
+    @media = MediaAttachment.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i))
 
-    media
+    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:video?)
   end
 
   def language_from_option(str)
@@ -82,8 +111,68 @@ class PostStatusService < BaseService
     Redis.current
   end
 
-  def bump_potential_friendship(account, status)
-    return if !status.reply? || account.following?(status.in_reply_to_account_id)
-    PotentialFriendshipTracker.record(account.id, status.in_reply_to_account_id, :reply)
+  def scheduled?
+    @scheduled_at.present?
+  end
+
+  def idempotency_key
+    "idempotency:status:#{@account.id}:#{@options[:idempotency]}"
+  end
+
+  def idempotency_given?
+    @options[:idempotency].present?
+  end
+
+  def idempotency_duplicate
+    if scheduled?
+      @account.schedule_statuses.find(@idempotency_duplicate)
+    else
+      @account.statuses.find(@idempotency_duplicate)
+    end
+  end
+
+  def idempotency_duplicate?
+    @idempotency_duplicate = redis.get(idempotency_key)
+  end
+
+  def scheduled_in_the_past?
+    @scheduled_at.present? && @scheduled_at <= Time.now.utc + MIN_SCHEDULE_OFFSET
+  end
+
+  def bump_potential_friendship!
+    return if !@status.reply? || @account.id == @status.in_reply_to_account_id
+    ActivityTracker.increment('activity:interactions')
+    return if @account.following?(@status.in_reply_to_account_id)
+    PotentialFriendshipTracker.record(@account.id, @status.in_reply_to_account_id, :reply)
+  end
+
+  def status_attributes
+    {
+      text: @text,
+      media_attachments: @media || [],
+      thread: @in_reply_to,
+      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],
+    }
+  end
+
+  def scheduled_status_attributes
+    {
+      scheduled_at: @scheduled_at,
+      media_attachments: @media || [],
+      params: scheduled_options,
+    }
+  end
+
+  def scheduled_options
+    @options.tap do |options_hash|
+      options_hash[:in_reply_to_id] = options_hash.delete(:thread)&.id
+      options_hash[:application_id] = options_hash.delete(:application)&.id
+      options_hash[:scheduled_at]   = nil
+      options_hash[:idempotency]    = nil
+    end
   end
 end
diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb
index 4f771ff7233966eb307267e805b199eca6cd1576..076dedacab97dfed799c5c417b4ada969e0555e4 100644
--- a/app/services/precompute_feed_service.rb
+++ b/app/services/precompute_feed_service.rb
@@ -3,6 +3,7 @@
 class PrecomputeFeedService < BaseService
   def call(account)
     FeedManager.instance.populate_feed(account)
+  ensure
     Redis.current.del("account:#{account.id}:regeneration")
   end
 end
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 2ed6698cf28eba366b800e3055b744aba46bc697..2595c5fd3668c9743e3eed5d318b007c6ac1de15 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -25,7 +25,7 @@ class ProcessMentionsService < BaseService
         end
       end
 
-      next match if mention_undeliverable?(mentioned_account)
+      next match if mention_undeliverable?(mentioned_account) || mentioned_account&.suspended
 
       mentions << mentioned_account.mentions.where(status: status).first_or_create(status: status)
 
@@ -47,7 +47,7 @@ class ProcessMentionsService < BaseService
     mentioned_account = mention.account
 
     if mentioned_account.local?
-      LocalNotificationWorker.perform_async(mention.id)
+      LocalNotificationWorker.perform_async(mentioned_account.id, mention.id, mention.class.name)
     elsif mentioned_account.ostatus? && !@status.stream_entry.hidden?
       NotificationWorker.perform_async(ostatus_xml, @status.account_id, mentioned_account.id)
     elsif mentioned_account.activitypub?
@@ -60,11 +60,13 @@ class ProcessMentionsService < BaseService
   end
 
   def activitypub_json
-    @activitypub_json ||= Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
+    return @activitypub_json if defined?(@activitypub_json)
+    payload = ActiveModelSerializers::SerializableResource.new(
       @status,
       serializer: ActivityPub::ActivitySerializer,
       adapter: ActivityPub::Adapter
-    ).as_json).sign!(@status.account))
+    ).as_json
+    @activitypub_json = Oj.dump(@status.distributable? ? ActivityPub::LinkedDataSignature.new(payload).sign!(@status.account) : payload)
   end
 
   def resolve_account_service
diff --git a/app/services/pubsubhubbub/subscribe_service.rb b/app/services/pubsubhubbub/subscribe_service.rb
index 2dba05b12f1c362004c8e432558af962fb02a01b..550da632812a5163d091ed35ca5b95d10c7cac3b 100644
--- a/app/services/pubsubhubbub/subscribe_service.rb
+++ b/app/services/pubsubhubbub/subscribe_service.rb
@@ -19,31 +19,18 @@ class Pubsubhubbub::SubscribeService < BaseService
   private
 
   def process_subscribe
-    case subscribe_status
-    when :invalid_topic
+    if account.nil?
       ['Invalid topic URL', 422]
-    when :invalid_callback
+    elsif !valid_callback?
       ['Invalid callback URL', 422]
-    when :callback_not_allowed
+    elsif blocked_domain?
       ['Callback URL not allowed', 403]
-    when :valid
+    else
       confirm_subscription
       ['', 202]
     end
   end
 
-  def subscribe_status
-    if account.nil?
-      :invalid_topic
-    elsif !valid_callback?
-      :invalid_callback
-    elsif blocked_domain?
-      :callback_not_allowed
-    else
-      :valid
-    end
-  end
-
   def confirm_subscription
     subscription = locate_subscription
     Pubsubhubbub::ConfirmationWorker.perform_async(subscription.id, 'subscribe', secret, lease_seconds)
@@ -58,12 +45,7 @@ class Pubsubhubbub::SubscribeService < BaseService
   end
 
   def locate_subscription
-    subscription = Subscription.find_by(account: account, callback_url: callback)
-
-    if subscription.nil?
-      subscription = Subscription.new(account: account, callback_url: callback)
-    end
-
+    subscription = Subscription.find_or_initialize_by(account: account, callback_url: callback)
     subscription.domain = domain
     subscription.save!
     subscription
diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb
index 0ee8bac2f24c5bc7a6e9620ca5ab5c04833d6500..33ddef8b88d9482d63b0128ea5a9a53b96e13a6b 100644
--- a/app/services/reblog_service.rb
+++ b/app/services/reblog_service.rb
@@ -44,6 +44,7 @@ class ReblogService < BaseService
   end
 
   def bump_potential_friendship(account, reblog)
+    ActivityTracker.increment('activity:interactions')
     return if account.following?(reblog.reblog.account_id)
     PotentialFriendshipTracker.record(account.id, reblog.reblog.account_id, :reblog)
   end
diff --git a/app/services/reject_follow_service.rb b/app/services/reject_follow_service.rb
index c1f7bcb6069b0ef10b78a4129668fcddd7f6619b..a91266aa4b65b6447e1558cdc7373fda46a50aed 100644
--- a/app/services/reject_follow_service.rb
+++ b/app/services/reject_follow_service.rb
@@ -19,11 +19,11 @@ class RejectFollowService < BaseService
   end
 
   def build_json(follow_request)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
+    ActiveModelSerializers::SerializableResource.new(
       follow_request,
       serializer: ActivityPub::RejectFollowSerializer,
       adapter: ActivityPub::Adapter
-    ).as_json).sign!(follow_request.target_account))
+    ).to_json
   end
 
   def build_xml(follow_request)
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
index 238099169135e57860b412930b65310cbff8e910..11d28e783d04c86d5c48ccca49370badc3311e34 100644
--- a/app/services/remove_status_service.rb
+++ b/app/services/remove_status_service.rb
@@ -8,7 +8,7 @@ class RemoveStatusService < BaseService
     @status       = status
     @account      = status.account
     @tags         = status.tags.pluck(:name).to_a
-    @mentions     = status.mentions.includes(:account).to_a
+    @mentions     = status.active_mentions.includes(:account).to_a
     @reblogs      = status.reblogs.to_a
     @stream_entry = status.stream_entry
     @options      = options
@@ -21,7 +21,6 @@ class RemoveStatusService < BaseService
     remove_from_hashtags
     remove_from_public
     remove_from_media if status.media_attachments.any?
-    remove_from_direct if status.direct_visibility?
 
     @status.destroy!
 
@@ -43,13 +42,13 @@ class RemoveStatusService < BaseService
   end
 
   def remove_from_followers
-    @account.followers_for_local_distribution.find_each do |follower|
+    @account.followers_for_local_distribution.reorder(nil).find_each do |follower|
       FeedManager.instance.unpush_from_home(follower, @status)
     end
   end
 
   def remove_from_lists
-    @account.lists_for_local_distribution.select(:id, :account_id).find_each do |list|
+    @account.lists_for_local_distribution.select(:id, :account_id).reorder(nil).find_each do |list|
       FeedManager.instance.unpush_from_list(list, @status)
     end
   end
@@ -90,6 +89,18 @@ class RemoveStatusService < BaseService
     ActivityPub::DeliveryWorker.push_bulk(@account.followers.inboxes) do |inbox_url|
       [signed_activity_json, @account.id, inbox_url]
     end
+
+    relay! if relayable?
+  end
+
+  def relayable?
+    @status.public_visibility?
+  end
+
+  def relay!
+    ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
+      [signed_activity_json, @account.id, inbox_url]
+    end
   end
 
   def salmon_xml
@@ -141,13 +152,6 @@ class RemoveStatusService < BaseService
     Redis.current.publish('timeline:public:local:media', @payload) if @status.local?
   end
 
-  def remove_from_direct
-    @mentions.each do |mention|
-      Redis.current.publish("timeline:direct:#{mention.account.id}", @payload) if mention.account.local?
-    end
-    Redis.current.publish("timeline:direct:#{@account.id}", @payload) if @account.local?
-  end
-
   def redis
     Redis.current
   end
diff --git a/app/services/report_service.rb b/app/services/report_service.rb
index c06488a6de1628ce9491c3387b07950b173eba06..1bcc1c0d56c3a7e3e15e82ecbf5eccc6078ea9c7 100644
--- a/app/services/report_service.rb
+++ b/app/services/report_service.rb
@@ -26,7 +26,10 @@ class ReportService < BaseService
   end
 
   def notify_staff!
+    return if @report.unresolved_siblings?
+
     User.staff.includes(:account).each do |u|
+      next unless u.allows_report_emails?
       AdminMailer.new_report(u.account, @report).deliver_later
     end
   end
@@ -49,6 +52,6 @@ class ReportService < BaseService
   end
 
   def some_local_account
-    @some_local_account ||= Account.local.where(suspended: false).first
+    @some_local_account ||= Account.representative
   end
 end
diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb
index 4323e7f06d57f77c8fe37a618ba463a7faddf3c8..4ff351c5f72644253390a6c05ba7fb3b3b7dbcb5 100644
--- a/app/services/resolve_account_service.rb
+++ b/app/services/resolve_account_service.rb
@@ -9,17 +9,28 @@ class ResolveAccountService < BaseService
   # Find or create a local account for a remote user.
   # When creating, look up the user's webfinger and fetch all
   # important information from their feed
-  # @param [String] uri User URI in the form of username@domain
+  # @param [String, Account] uri User URI in the form of username@domain
+  # @param [Hash] options
   # @return [Account]
-  def call(uri, update_profile = true, redirected = nil)
-    @username, @domain = uri.split('@')
-    @update_profile    = update_profile
+  def call(uri, options = {})
+    @options = options
 
-    return Account.find_local(@username) if TagManager.instance.local_domain?(@domain)
+    if uri.is_a?(Account)
+      @account  = uri
+      @username = @account.username
+      @domain   = @account.domain
+      uri       = "#{@username}@#{@domain}"
+
+      return @account if @account.local? || !webfinger_update_due?
+    else
+      @username, @domain = uri.split('@')
 
-    @account = Account.find_remote(@username, @domain)
+      return Account.find_local(@username) if TagManager.instance.local_domain?(@domain)
 
-    return @account unless webfinger_update_due?
+      @account = Account.find_remote(@username, @domain)
+
+      return @account unless webfinger_update_due?
+    end
 
     Rails.logger.debug "Looking up webfinger for #{uri}"
 
@@ -30,8 +41,8 @@ class ResolveAccountService < BaseService
     if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
       @username = confirmed_username
       @domain   = confirmed_domain
-    elsif redirected.nil?
-      return call("#{confirmed_username}@#{confirmed_domain}", update_profile, true)
+    elsif options[:redirected].nil?
+      return call("#{confirmed_username}@#{confirmed_domain}", options.merge(redirected: true))
     else
       Rails.logger.debug 'Requested and returned acct URIs do not match'
       return
@@ -76,7 +87,7 @@ class ResolveAccountService < BaseService
   end
 
   def webfinger_update_due?
-    @account.nil? || @account.possibly_stale?
+    @account.nil? || ((!@options[:skip_webfinger] || @account.ostatus?) && @account.possibly_stale?)
   end
 
   def activitypub_ready?
@@ -93,7 +104,7 @@ class ResolveAccountService < BaseService
   end
 
   def update_profile?
-    @update_profile
+    @options[:update_profile]
   end
 
   def handle_activitypub
diff --git a/app/services/resolve_url_service.rb b/app/services/resolve_url_service.rb
index a068c1ed86a2ae21f31ec9f58f34741d85eaac2b..ed0c569230f64f3e459eb7f893a3f55738fe8fbf 100644
--- a/app/services/resolve_url_service.rb
+++ b/app/services/resolve_url_service.rb
@@ -2,11 +2,13 @@
 
 class ResolveURLService < BaseService
   include JsonLdHelper
+  include Authorization
 
   attr_reader :url
 
-  def call(url)
+  def call(url, on_behalf_of: nil)
     @url = url
+    @on_behalf_of = on_behalf_of
 
     return process_local_url if local_url?
 
@@ -18,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))
+    elsif equals_or_includes_any?(type, %w(Note Article Image Video Page))
       FetchRemoteStatusService.new.call(atom_url, body, protocol)
     end
   end
@@ -84,6 +86,10 @@ class ResolveURLService < BaseService
 
   def check_local_status(status)
     return if status.nil?
-    status if status.public_visibility? || status.unlisted_visibility?
+    authorize_with @on_behalf_of, status, :show?
+    status
+  rescue Mastodon::NotPermittedError
+    # Do not disclose the existence of status the user is not authorized to see
+    nil
   end
 end
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 5bb395942da0bec28894e68d02db0600b8c84beb..1c31e0509a8549ba0de1f20c6cf3cf380ce92ec7 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -34,6 +34,8 @@ class SearchService < BaseService
                             .compact
 
     statuses.reject { |status| StatusFilter.new(status, account).filtered? }
+  rescue Faraday::ConnectionFailed
+    []
   end
 
   def perform_hashtags_search!
@@ -53,7 +55,7 @@ class SearchService < BaseService
   end
 
   def url_resource
-    @_url_resource ||= ResolveURLService.new.call(query)
+    @_url_resource ||= ResolveURLService.new.call(query, on_behalf_of: @account)
   end
 
   def url_resource_symbol
diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb
index 708d15e37d9284084daa4c8243f7aee65ae26d35..1bc2314de7156e802fe75c8d0139e00afb4147ea 100644
--- a/app/services/suspend_account_service.rb
+++ b/app/services/suspend_account_service.rb
@@ -1,6 +1,42 @@
 # frozen_string_literal: true
 
 class SuspendAccountService < BaseService
+  ASSOCIATIONS_ON_SUSPEND = %w(
+    account_pins
+    active_relationships
+    block_relationships
+    blocked_by_relationships
+    conversation_mutes
+    conversations
+    custom_filters
+    domain_blocks
+    favourites
+    follow_requests
+    list_accounts
+    media_attachments
+    mute_relationships
+    muted_by_relationships
+    notifications
+    owned_lists
+    passive_relationships
+    report_notes
+    scheduled_statuses
+    status_pins
+    stream_entries
+    subscriptions
+  ).freeze
+
+  ASSOCIATIONS_ON_DESTROY = %w(
+    reports
+    targeted_moderation_notes
+    targeted_reports
+  ).freeze
+
+  # Suspend an account and remove as much of its data as possible
+  # @param [Account]
+  # @param [Hash] options
+  # @option [Boolean] :including_user Remove the user record as well
+  # @option [Boolean] :destroy Remove the account record instead of suspending
   def call(account, **options)
     @account = account
     @options = options
@@ -8,63 +44,87 @@ class SuspendAccountService < BaseService
     purge_user!
     purge_profile!
     purge_content!
-    unsubscribe_push_subscribers!
   end
 
   private
 
   def purge_user!
-    if @options[:remove_user]
-      @account.user&.destroy
+    return if !@account.local? || @account.user.nil?
+
+    if @options[:including_user]
+      @account.user.destroy
     else
-      @account.user&.disable!
+      @account.user.disable!
     end
   end
 
   def purge_content!
-    ActivityPub::RawDistributionWorker.perform_async(delete_actor_json, @account.id) if @account.local?
+    distribute_delete_actor! if @account.local?
 
     @account.statuses.reorder(nil).find_in_batches do |statuses|
-      BatchedRemoveStatusService.new.call(statuses)
+      BatchedRemoveStatusService.new.call(statuses, skip_side_effects: @options[:destroy])
     end
 
-    [
-      @account.media_attachments,
-      @account.stream_entries,
-      @account.notifications,
-      @account.favourites,
-      @account.active_relationships,
-      @account.passive_relationships,
-    ].each do |association|
-      destroy_all(association)
+    associations_for_destruction.each do |association_name|
+      destroy_all(@account.public_send(association_name))
     end
+
+    @account.destroy if @options[:destroy]
   end
 
   def purge_profile!
-    @account.suspended      = true
-    @account.display_name   = ''
-    @account.note           = ''
-    @account.statuses_count = 0
+    # If the account is going to be destroyed
+    # there is no point wasting time updating
+    # its values first
+
+    return if @options[:destroy]
+
+    @account.silenced         = false
+    @account.suspended        = true
+    @account.locked           = false
+    @account.display_name     = ''
+    @account.note             = ''
+    @account.fields           = {}
+    @account.statuses_count   = 0
+    @account.followers_count  = 0
+    @account.following_count  = 0
+    @account.moved_to_account = nil
     @account.avatar.destroy
     @account.header.destroy
     @account.save!
   end
 
-  def unsubscribe_push_subscribers!
-    destroy_all(@account.subscriptions)
-  end
-
   def destroy_all(association)
     association.in_batches.destroy_all
   end
 
+  def distribute_delete_actor!
+    ActivityPub::DeliveryWorker.push_bulk(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
 
-    Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
+    @delete_actor_json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
+  end
+
+  def delivery_inboxes
+    Account.inboxes + Relay.enabled.pluck(:inbox_url)
+  end
+
+  def associations_for_destruction
+    if @options[:destroy]
+      ASSOCIATIONS_ON_SUSPEND + ASSOCIATIONS_ON_DESTROY
+    else
+      ASSOCIATIONS_ON_SUSPEND
+    end
   end
 end
diff --git a/app/services/unblock_service.rb b/app/services/unblock_service.rb
index 869f62d1c53f7366f59b8de8fca51ce78b3da437..72fc5ab150d68702d953fd4efa495945b9bdacaa 100644
--- a/app/services/unblock_service.rb
+++ b/app/services/unblock_service.rb
@@ -20,11 +20,11 @@ class UnblockService < BaseService
   end
 
   def build_json(unblock)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
+    ActiveModelSerializers::SerializableResource.new(
       unblock,
       serializer: ActivityPub::UndoBlockSerializer,
       adapter: ActivityPub::Adapter
-    ).as_json).sign!(unblock.account))
+    ).to_json
   end
 
   def build_xml(block)
diff --git a/app/services/unfollow_service.rb b/app/services/unfollow_service.rb
index 73a64929fa19beb643a542e63d20a6c09e453713..95da2a667b32c03ba5a1be1a6da8acd2bfbd579e 100644
--- a/app/services/unfollow_service.rb
+++ b/app/services/unfollow_service.rb
@@ -20,6 +20,7 @@ class UnfollowService < BaseService
 
     follow.destroy!
     create_notification(follow) unless @target_account.local?
+    create_reject_notification(follow) if @target_account.local? && !@source_account.local?
     UnmergeWorker.perform_async(@target_account.id, @source_account.id)
     follow
   end
@@ -42,12 +43,26 @@ class UnfollowService < BaseService
     end
   end
 
+  def create_reject_notification(follow)
+    # Rejecting an already-existing follow request
+    return unless follow.account.activitypub?
+    ActivityPub::DeliveryWorker.perform_async(build_reject_json(follow), follow.target_account_id, follow.account.inbox_url)
+  end
+
   def build_json(follow)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
+    ActiveModelSerializers::SerializableResource.new(
       follow,
       serializer: ActivityPub::UndoFollowSerializer,
       adapter: ActivityPub::Adapter
-    ).as_json).sign!(follow.account))
+    ).to_json
+  end
+
+  def build_reject_json(follow)
+    ActiveModelSerializers::SerializableResource.new(
+      follow,
+      serializer: ActivityPub::RejectFollowSerializer,
+      adapter: ActivityPub::Adapter
+    ).to_json
   end
 
   def build_xml(follow)
diff --git a/app/services/update_account_service.rb b/app/services/update_account_service.rb
index 09ea377e731500458164bba65b37eb6161bacdd4..01756a73d4bbeafdc8cef1af40849c59b916a575 100644
--- a/app/services/update_account_service.rb
+++ b/app/services/update_account_service.rb
@@ -2,20 +2,34 @@
 
 class UpdateAccountService < BaseService
   def call(account, params, raise_error: false)
-    was_locked = account.locked
+    was_locked    = account.locked
     update_method = raise_error ? :update! : :update
+
     account.send(update_method, params).tap do |ret|
       next unless ret
+
       authorize_all_follow_requests(account) if was_locked && !account.locked
+      check_links(account)
+      process_hashtags(account)
     end
+  rescue Mastodon::DimensionsValidationError => de
+    account.errors.add(:avatar, de.message)
+    false
   end
 
   private
 
   def authorize_all_follow_requests(account)
-    follow_requests = FollowRequest.where(target_account: account)
-    AuthorizeFollowWorker.push_bulk(follow_requests) do |req|
+    AuthorizeFollowWorker.push_bulk(FollowRequest.where(target_account: account).select(:account_id, :target_account_id)) do |req|
       [req.account_id, req.target_account_id]
     end
   end
+
+  def check_links(account)
+    VerifyAccountLinksWorker.perform_async(account.id)
+  end
+
+  def process_hashtags(account)
+    account.tags_as_strings = Extractor.extract_hashtags(account.note)
+  end
 end
diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c6557876137f778c0aefbebba8430b56d42e1421
--- /dev/null
+++ b/app/services/verify_link_service.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+class VerifyLinkService < BaseService
+  def call(field)
+    @link_back = ActivityPub::TagManager.instance.url_for(field.account)
+    @url       = field.value_for_verification
+
+    perform_request!
+
+    return unless link_back_present?
+
+    field.mark_verified!
+  rescue HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e
+    Rails.logger.debug "Error fetching link #{@url}: #{e}"
+    nil
+  end
+
+  private
+
+  def perform_request!
+    @body = Request.new(:get, @url).add_headers('Accept' => 'text/html').perform do |res|
+      res.code != 200 ? nil : res.body_with_limit
+    end
+  end
+
+  def link_back_present?
+    return false if @body.blank?
+
+    links = Nokogiri::HTML(@body).xpath('//a[contains(concat(" ", normalize-space(@rel), " "), " me ")]|//link[contains(concat(" ", normalize-space(@rel), " "), " me ")]')
+
+    if links.any? { |link| link['href'] == @link_back }
+      true
+    elsif links.empty?
+      false
+    else
+      link_redirects_back?(links.first['href'])
+    end
+  end
+
+  def link_redirects_back?(test_url)
+    redirect_to_url = Request.new(:head, test_url, follow: false).perform do |res|
+      res.headers['Location']
+    end
+
+    redirect_to_url == @link_back
+  end
+end
diff --git a/app/validators/blacklisted_email_validator.rb b/app/validators/blacklisted_email_validator.rb
index 3f203f49a6ee7dce10a526f6c201aa4ed3d8e534..a2061fdd311069b06d0ff3444c3f911890d1ca86 100644
--- a/app/validators/blacklisted_email_validator.rb
+++ b/app/validators/blacklisted_email_validator.rb
@@ -2,31 +2,32 @@
 
 class BlacklistedEmailValidator < ActiveModel::Validator
   def validate(user)
-    user.errors.add(:email, I18n.t('users.invalid_email')) if blocked_email?(user.email)
+    @email = user.email
+    user.errors.add(:email, I18n.t('users.invalid_email')) if blocked_email?
   end
 
   private
 
-  def blocked_email?(value)
-    on_blacklist?(value) || not_on_whitelist?(value)
+  def blocked_email?
+    on_blacklist? || not_on_whitelist?
   end
 
-  def on_blacklist?(value)
-    return true if EmailDomainBlock.block?(value)
+  def on_blacklist?
+    return true if EmailDomainBlock.block?(@email)
     return false if Rails.configuration.x.email_domains_blacklist.blank?
 
     domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
     regexp  = Regexp.new("@(.+\\.)?(#{domains})", true)
 
-    value =~ regexp
+    @email =~ regexp
   end
 
-  def not_on_whitelist?(value)
+  def not_on_whitelist?
     return false if Rails.configuration.x.email_domains_whitelist.blank?
 
     domains = Rails.configuration.x.email_domains_whitelist.gsub('.', '\.')
     regexp  = Regexp.new("@(.+\\.)?(#{domains})$", true)
 
-    value !~ regexp
+    @email !~ regexp
   end
 end
diff --git a/app/validators/disallowed_hashtags_validator.rb b/app/validators/disallowed_hashtags_validator.rb
index 22c027b0fcac07819c5ae77e6658990b554a881d..ee06b20f6b49bd03f5f71a86daafa4c5dda3a748 100644
--- a/app/validators/disallowed_hashtags_validator.rb
+++ b/app/validators/disallowed_hashtags_validator.rb
@@ -4,14 +4,19 @@ class DisallowedHashtagsValidator < ActiveModel::Validator
   def validate(status)
     return unless status.local? && !status.reblog?
 
-    tags = Extractor.extract_hashtags(status.text)
-    tags.keep_if { |tag| disallowed_hashtags.include? tag.downcase }
+    @status = status
+    tags    = select_tags
 
     status.errors.add(:text, I18n.t('statuses.disallowed_hashtags', tags: tags.join(', '), count: tags.size)) unless tags.empty?
   end
 
   private
 
+  def select_tags
+    tags = Extractor.extract_hashtags(@status.text)
+    tags.keep_if { |tag| disallowed_hashtags.include? tag.downcase }
+  end
+
   def disallowed_hashtags
     return @disallowed_hashtags if @disallowed_hashtags
 
diff --git a/app/validators/email_mx_validator.rb b/app/validators/email_mx_validator.rb
index e9e6b56e876fca750763ad4c283604bee2df2425..5b4c684b2c4b449ee98c8d693ce1b25cd5328701 100644
--- a/app/validators/email_mx_validator.rb
+++ b/app/validators/email_mx_validator.rb
@@ -4,7 +4,6 @@ require 'resolv'
 
 class EmailMxValidator < ActiveModel::Validator
   def validate(user)
-    return if Rails.env.test? || Rails.env.development?
     user.errors.add(:email, I18n.t('users.invalid_email')) if invalid_mx?(user.email)
   end
 
@@ -15,13 +14,23 @@ class EmailMxValidator < ActiveModel::Validator
 
     return true if domain.nil?
 
-    records = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
-    records = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.exchange.to_s } if records.empty?
+    hostnames = []
+    ips       = []
 
-    records.empty? || on_blacklist?(records)
+    Resolv::DNS.open do |dns|
+      dns.timeouts = 1
+
+      hostnames = dns.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
+
+      ([domain] + hostnames).uniq.each do |hostname|
+        ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s })
+      end
+    end
+
+    ips.empty? || on_blacklist?(hostnames + ips)
   end
 
   def on_blacklist?(values)
-    EmailDomainBlock.where(domain: values).any?
+    EmailDomainBlock.where(domain: values.uniq).any?
   end
 end
diff --git a/app/validators/follow_limit_validator.rb b/app/validators/follow_limit_validator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..409bf01763b45e89840f7b1bb386861b162683ad
--- /dev/null
+++ b/app/validators/follow_limit_validator.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class FollowLimitValidator < ActiveModel::Validator
+  LIMIT = ENV.fetch('MAX_FOLLOWS_THRESHOLD', 7_500).to_i
+  RATIO = ENV.fetch('MAX_FOLLOWS_RATIO', 1.1).to_f
+
+  def validate(follow)
+    return if follow.account.nil? || !follow.account.local?
+    follow.errors.add(:base, I18n.t('users.follow_limit_reached', limit: self.class.limit_for_account(follow.account))) if limit_reached?(follow.account)
+  end
+
+  class << self
+    def limit_for_account(account)
+      if account.following_count < LIMIT
+        LIMIT
+      else
+        [(account.followers_count * RATIO).round, LIMIT].max
+      end
+    end
+  end
+
+  private
+
+  def limit_reached?(account)
+    account.following_count >= self.class.limit_for_account(account)
+  end
+end
diff --git a/app/validators/note_length_validator.rb b/app/validators/note_length_validator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5ff6df6df24279b4a1c716ab1ca7078a3b148d12
--- /dev/null
+++ b/app/validators/note_length_validator.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class NoteLengthValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    record.errors.add(attribute, I18n.t('statuses.over_character_limit', max: options[:maximum])) if too_long?(value)
+  end
+
+  private
+
+  def too_long?(value)
+    countable_text(value).mb_chars.grapheme_length > options[:maximum]
+  end
+
+  def countable_text(value)
+    return '' if value.nil?
+
+    value.dup.tap do |new_text|
+      new_text.gsub!(FetchLinkCardService::URL_PATTERN, 'x' * 23)
+      new_text.gsub!(Account::MENTION_RE, '@\2')
+    end
+  end
+end
diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb
index 429ad6c383bedaf961be2a4d342db35c998cddd9..8daa46857b15a9315fc1878e654648a9feaacc98 100644
--- a/app/validators/status_length_validator.rb
+++ b/app/validators/status_length_validator.rb
@@ -5,27 +5,29 @@ class StatusLengthValidator < ActiveModel::Validator
 
   def validate(status)
     return unless status.local? && !status.reblog?
-    status.errors.add(:text, I18n.t('statuses.over_character_limit', max: MAX_CHARS)) if too_long?(status)
+
+    @status = status
+    status.errors.add(:text, I18n.t('statuses.over_character_limit', max: MAX_CHARS)) if too_long?
   end
 
   private
 
-  def too_long?(status)
-    countable_length(status) > MAX_CHARS
+  def too_long?
+    countable_length > MAX_CHARS
   end
 
-  def countable_length(status)
-    total_text(status).mb_chars.grapheme_length
+  def countable_length
+    total_text.mb_chars.grapheme_length
   end
 
-  def total_text(status)
-    [status.spoiler_text, countable_text(status)].join
+  def total_text
+    [@status.spoiler_text, countable_text].join
   end
 
-  def countable_text(status)
-    return '' if status.text.nil?
+  def countable_text
+    return '' if @status.text.nil?
 
-    status.text.dup.tap do |new_text|
+    @status.text.dup.tap do |new_text|
       new_text.gsub!(FetchLinkCardService::URL_PATTERN, 'x' * 23)
       new_text.gsub!(Account::MENTION_RE, '@\2')
     end
diff --git a/app/validators/unreserved_username_validator.rb b/app/validators/unreserved_username_validator.rb
index c2311a89abbf0f776b223296d3fa701ed3001cf2..634ceb06e6eb4def92efd23d1a33f094e4d436ca 100644
--- a/app/validators/unreserved_username_validator.rb
+++ b/app/validators/unreserved_username_validator.rb
@@ -2,20 +2,22 @@
 
 class UnreservedUsernameValidator < ActiveModel::Validator
   def validate(account)
-    return if account.username.nil?
-    account.errors.add(:username, I18n.t('accounts.reserved_username')) if reserved_username?(account.username)
+    @username = account.username
+    return if @username.nil?
+
+    account.errors.add(:username, I18n.t('accounts.reserved_username')) if reserved_username?
   end
 
   private
 
-  def pam_controlled?(value)
+  def pam_controlled?
     return false unless Devise.pam_authentication && Devise.pam_controlled_service
-    Rpam2.account(Devise.pam_controlled_service, value).present?
+    Rpam2.account(Devise.pam_controlled_service, @username).present?
   end
 
-  def reserved_username?(value)
-    return true if pam_controlled?(value)
+  def reserved_username?
+    return true if pam_controlled?
     return false unless Setting.reserved_usernames
-    Setting.reserved_usernames.include?(value.downcase)
+    Setting.reserved_usernames.include?(@username.downcase)
   end
 end
diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb
index f39560d90aca48f0d5a783b7e60eee3787c85e0b..d95a03fbf86cda5494459f1c45cfe4eb642fe60a 100644
--- a/app/validators/url_validator.rb
+++ b/app/validators/url_validator.rb
@@ -8,7 +8,7 @@ class UrlValidator < ActiveModel::EachValidator
   private
 
   def compliant?(url)
-    parsed_url = Addressable::URI.parse(url).normalize
-    !parsed_url.nil? && %w(http https).include?(parsed_url.scheme) && parsed_url.host
+    parsed_url = Addressable::URI.parse(url)
+    parsed_url && %w(http https).include?(parsed_url.scheme) && parsed_url.host
   end
 end
diff --git a/app/views/about/_administration.html.haml b/app/views/about/_administration.html.haml
deleted file mode 100644
index 02286d68b7be589708749beb37e0fbb6213843d5..0000000000000000000000000000000000000000
--- a/app/views/about/_administration.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-.account
-  .account__wrapper
-    - if @instance_presenter.contact_account
-      = link_to TagManager.instance.url_for(@instance_presenter.contact_account), class: 'account__display-name' do
-        .account__avatar-wrapper
-          .account__avatar{ style: "background-image: url(#{@instance_presenter.contact_account.avatar.url})" }
-        %span.display-name
-          %bdi
-            %strong.display-name__html.emojify= display_name(@instance_presenter.contact_account, custom_emojify: true)
-          %span.display-name__account @#{@instance_presenter.contact_account.acct}
-    - else
-      .account__display-name
-        .account__avatar-wrapper
-          .account__avatar{ style: "background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)})" }
-        %span.display-name
-          %strong= t 'about.contact_missing'
-          %span.display-name__account= t 'about.contact_unavailable'
-
-    = link_to t('about.learn_more'), about_more_path, class: 'button button-alternative'
diff --git a/app/views/about/_contact.html.haml b/app/views/about/_contact.html.haml
deleted file mode 100644
index 3215d50b5315cc4e0761e877bbf73b5c581c5453..0000000000000000000000000000000000000000
--- a/app/views/about/_contact.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-.panel
-  .panel-header
-    = succeed ':' do
-      = t 'about.contact'
-    - if contact.site_contact_email.present?
-      = mail_to contact.site_contact_email, nil, title: contact.site_contact_email
-    - else
-      %span= t 'about.contact_unavailable'
-  .panel-body
-    - if contact.contact_account
-      .owner
-        .avatar= image_tag contact.contact_account.avatar.url
-        .name
-          = link_to TagManager.instance.url_for(contact.contact_account) do
-            %span.display_name.emojify= display_name(contact.contact_account, custom_emojify: true)
-            %span.username @#{contact.contact_account.acct}
-    - else
-      .owner
-        .avatar= image_tag full_asset_url('avatars/original/missing.png', skip_pipeline: true)
-        .name
-          %span.display_name= t 'about.contact_missing'
-          %span.username= t 'about.contact_unavailable'
diff --git a/app/views/about/_registration.html.haml b/app/views/about/_registration.html.haml
index 6ca1d71290b9e702c77091a9a022fda0373fec34..ee4f8fe2e61d8994af7ce0888ff72d8981c2e146 100644
--- a/app/views/about/_registration.html.haml
+++ b/app/views/about/_registration.html.haml
@@ -1,13 +1,10 @@
 = simple_form_for(new_user, url: user_registration_path) do |f|
   = f.simple_fields_for :account do |account_fields|
-    .input-with-append
-      = account_fields.input :username, autofocus: true, placeholder: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off' }
-      .append
-        = "@#{site_hostname}"
+    = 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
 
-  = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }
-  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
-  = 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' }
+  = 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
 
   .actions
     = f.button :button, t('auth.register'), type: :submit, class: 'button button-primary'
diff --git a/app/views/about/more.html.haml b/app/views/about/more.html.haml
index df072b8aec425ed234b2a4d0d3db1ec87d12265d..f94c7c06f8ce05a00dcffb6404948c54f5251bb4 100644
--- a/app/views/about/more.html.haml
+++ b/app/views/about/more.html.haml
@@ -5,39 +5,43 @@
   = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
   = render partial: 'shared/og'
 
-.landing-page
-  .header-wrapper.compact
-    .header
-      = render 'links'
+.grid-3
+  .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'
 
-      .container-alt.hero
-        .heading
-          %h3= t('about.description_headline', domain: site_hostname)
-          %p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
+  .column-1
+    .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: ''
 
-  .information-board
-    .container-alt
-      .information-board__sections
-        .information-board__section
-          %span= t 'about.user_count_before'
-          %strong= number_with_delimiter @instance_presenter.user_count
-          %span= t 'about.user_count_after'
-        .information-board__section
-          %span= t 'about.status_count_before'
-          %strong= number_with_delimiter @instance_presenter.status_count
-          %span= t 'about.status_count_after'
-        .information-board__section
-          %span= t 'about.domain_count_before'
-          %strong= number_with_delimiter @instance_presenter.domain_count
-          %span= t 'about.domain_count_after'
-      = render 'contact', contact: @instance_presenter
+  .column-2
+    .landing-page__information.contact-widget
+      %p
+        %strong= t 'about.administered_by'
 
-  .extended-description
-    .container-alt
-      = @instance_presenter.site_extended_description.html_safe.presence || t('about.extended_description_html')
+      = account_link_to(@instance_presenter.contact_account)
 
-  .footer-links
-    .container-alt
-      %p
-        = link_to t('about.source_code'), @instance_presenter.source_url
-        = " (#{@instance_presenter.version_number})"
+      - if @instance_presenter.site_contact_email.present?
+        %p.contact-widget__mail
+          %strong
+            = succeed ':' do
+              = t 'about.contact'
+          %br/
+          = mail_to @instance_presenter.site_contact_email, nil, title: @instance_presenter.site_contact_email
+
+  .column-3
+    .box-widget
+      .rich-formatting= @instance_presenter.site_extended_description.html_safe.presence || t('about.extended_description_html')
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index fba46d54b74755f0cfece97ce3b9eed99d3542f2..f5a78665d3d84c0ea68ef2c981aa5278eecfdef9 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -56,14 +56,14 @@
                 .information-board__section
                   %span= t 'about.user_count_before'
                   %strong= number_with_delimiter @instance_presenter.user_count
-                  %span= t 'about.user_count_after'
+                  %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'
+                  %span= t 'about.status_count_after', count: @instance_presenter.status_count
               .row__mascot
                 .landing-page__mascot
-                  = image_tag asset_pack_path('elephant_ui_plane.svg')
+                  = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('elephant_ui_plane.svg'), alt: ''
 
       - else
         .column-2.non-preview
@@ -88,14 +88,14 @@
                 .information-board__section
                   %span= t 'about.user_count_before'
                   %strong= number_with_delimiter @instance_presenter.user_count
-                  %span= t 'about.user_count_after'
+                  %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'
+                  %span= t 'about.status_count_after', count: @instance_presenter.status_count
               .row__mascot
                 .landing-page__mascot
-                  = image_tag asset_pack_path('elephant_ui_plane.svg')
+                  = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('elephant_ui_plane.svg'), alt: ''
 
       - if Setting.timeline_preview
         .column-3
@@ -110,7 +110,7 @@
                 %p= t 'about.about_mastodon_html'
               %div.contact
                 %h3= t 'about.administered_by'
-                = render 'administration'
+                = account_link_to(@instance_presenter.contact_account, link_to(t('about.learn_more'), about_more_path, class: 'button button-alternative'))
 
             = render 'features'
 
@@ -131,7 +131,7 @@
                 %p= t 'about.about_mastodon_html'
               %div.contact
                 %h3= t 'about.administered_by'
-                = render 'administration'
+                = account_link_to(@instance_presenter.contact_account, link_to(t('about.learn_more'), about_more_path, class: 'button button-alternative'))
 
             = render 'features'
 
diff --git a/app/views/about/terms.html.haml b/app/views/about/terms.html.haml
index c7d36ed47a875b5ecb2088067d638aebd778aa09..9d076a91b41982373e9c60e352dc746f75ea1438 100644
--- a/app/views/about/terms.html.haml
+++ b/app/views/about/terms.html.haml
@@ -1,11 +1,9 @@
 - content_for :page_title do
   = t('terms.title', instance: site_hostname)
 
-.landing-page
-  .header-wrapper.compact
-    .header
-      = render 'links'
-
-  .extended-description
-    .container-alt
-      = @instance_presenter.site_terms.html_safe.presence || t('terms.body_html')
+.grid
+  .column-0
+    .box-widget
+      .rich-formatting= @instance_presenter.site_terms.html_safe.presence || t('terms.body_html')
+  .column-1
+    = render 'application/sidebar'
diff --git a/app/views/accounts/_bio.html.haml b/app/views/accounts/_bio.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..2ea34a0485fa30e450bb93d142eca5f5040d914f
--- /dev/null
+++ b/app/views/accounts/_bio.html.haml
@@ -0,0 +1,18 @@
+.public-account-bio
+  - unless account.fields.empty?
+    .account__header__fields
+      - account.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) }
+            - if field.verified?
+              %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?
+    .account__header__content.emojify= Formatter.instance.simplified_format(account, custom_emojify: true)
+
+  .public-account-bio__extra
+    = t 'accounts.joined', date: l(account.created_at, format: :month)
diff --git a/app/views/accounts/_follow_button.html.haml b/app/views/accounts/_follow_button.html.haml
deleted file mode 100644
index 558ced010f32053e831f315c7369ec0c07cb7811..0000000000000000000000000000000000000000
--- a/app/views/accounts/_follow_button.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
-- relationships ||= nil
-
-- unless account.memorial? || account.moved?
-  - if user_signed_in?
-    - requested = relationships ? relationships.requested[account.id].present? : current_account.requested?(account)
-    - following = relationships ? relationships.following[account.id].present? : current_account.following?(account)
-
-  - if user_signed_in? && current_account.id != account.id && !requested
-    .controls
-      - if following
-        = link_to (account.local? ? account_unfollow_path(account) : remote_unfollow_path(acct: account.acct)), data: { method: :post }, class: 'icon-button' do
-          = fa_icon 'user-times'
-          = t('accounts.unfollow')
-      - else
-        = link_to (account.local? ? account_follow_path(account) : authorize_follow_path(acct: account.acct)), data: { method: :post }, class: 'icon-button' do
-          = fa_icon 'user-plus'
-          = t('accounts.follow')
-  - elsif user_signed_in? && current_account.id == account.id
-    .controls
-      = link_to settings_profile_url, class: 'icon-button' do
-        = fa_icon 'pencil'
-        = t('settings.edit_profile')
-  - elsif !user_signed_in?
-    .controls
-      .remote-follow
-        = link_to (account.local? ? account_remote_follow_path(account) : "web+mastodon://follow?uri=#{account.uri}"), class: 'icon-button' do
-          = fa_icon 'user-plus'
-          = t('accounts.remote_follow')
diff --git a/app/views/accounts/_follow_grid.html.haml b/app/views/accounts/_follow_grid.html.haml
deleted file mode 100644
index fdcef84be2c57e1e6312db1eba77f593b4fe1d6e..0000000000000000000000000000000000000000
--- a/app/views/accounts/_follow_grid.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-.accounts-grid{ class: accounts.empty? ? 'empty' : '' }
-  - if accounts.empty?
-    = image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
-    = render partial: 'accounts/nothing_here'
-  - else
-    = render partial: 'accounts/grid_card', collection: accounts, as: :account, cached: !user_signed_in?
-
-= paginate follows
diff --git a/app/views/accounts/_follow_grid_hidden.html.haml b/app/views/accounts/_follow_grid_hidden.html.haml
deleted file mode 100644
index e970350e639e10c3293c2c78e910fbd980a8fc30..0000000000000000000000000000000000000000
--- a/app/views/accounts/_follow_grid_hidden.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-.accounts-grid.empty
-  = image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
-  %p.nothing-here= t('accounts.network_hidden')
diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml
deleted file mode 100644
index a59ed128e6e2c6e671a53bb2974fac4625b0af49..0000000000000000000000000000000000000000
--- a/app/views/accounts/_grid_card.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-.account-grid-card
-  .account-grid-card__header{ style: "background-image: url(#{account.header.url(:original)})" }
-    = render 'accounts/follow_button', account: account, relationships: @relationships
-  .account-grid-card__avatar
-    .avatar= image_tag account.avatar.url(:original)
-  .name
-    = link_to TagManager.instance.url_for(account) do
-      %span.display_name.emojify= display_name(account, custom_emojify: true)
-      %span.username
-        @#{account.local? ? account.local_username_and_domain : account.acct}
-        = fa_icon('lock') if account.locked?
-  .account__header__content.p-note.emojify= Formatter.instance.simplified_format(account)
diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml
index 4098d6778aadaeb52edb2799c74244eadf52d3ab..370e7e470f50dc6aa3decb02695fbce3afa058a4 100644
--- a/app/views/accounts/_header.html.haml
+++ b/app/views/accounts/_header.html.haml
@@ -1,51 +1,43 @@
-.card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
-  .card__illustration
-    = render 'accounts/follow_button', account: account
-    .avatar= image_tag account.avatar.url(:original), class: 'u-photo'
+.public-account-header{:class => ("inactive" if account.moved?)}
+  .public-account-header__image
+    = 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)
+    .public-account-header__tabs
+      .public-account-header__tabs__name
+        %h1
+          = display_name(account, custom_emojify: true)
+          %small
+            = acct(account)
+            = fa_icon('lock') if account.locked?
+      .public-account-header__tabs__tabs
+        .details-counters
+          .counter{ class: active_nav_class(short_account_url(account), short_account_with_replies_url(account), short_account_media_url(account)) }
+            = link_to short_account_url(account), class: 'u-url u-uid', title: number_with_delimiter(account.statuses_count) do
+              %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
+              %span.counter-label= t('accounts.posts', count: account.statuses_count)
 
-  .card__bio
-    %h1.name
-      %span.p-name.emojify= display_name(account, custom_emojify: true)
-      %small<
-        %span>< @#{account.local_username_and_domain}
-        = fa_icon('lock') if account.locked?
+          .counter{ class: active_nav_class(account_following_index_url(account)) }
+            = link_to account_following_index_url(account), title: number_with_delimiter(account.following_count) do
+              %span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
+              %span.counter-label= t('accounts.following', count: account.following_count)
 
-    - if account.bot?
-      .roles
-        .account-role.bot
-          = t 'accounts.roles.bot'
-    - elsif Setting.show_staff_badge
-      - if account.user_admin?
-        .roles
-          .account-role.admin
-            = t 'accounts.roles.admin'
-      - elsif account.user_moderator?
-        .roles
-          .account-role.moderator
-            = t 'accounts.roles.moderator'
+          .counter{ class: active_nav_class(account_followers_url(account)) }
+            = link_to account_followers_url(account), title: number_with_delimiter(account.followers_count) do
+              %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
+              %span.counter-label= t('accounts.followers', count: account.followers_count)
+        .spacer
+        .public-account-header__tabs__tabs__buttons
+          = account_action_button(account)
 
-    .bio
-      .account__header__content.p-note.emojify= Formatter.instance.simplified_format(account, custom_emojify: true)
+    .public-account-header__extra
+      = render 'accounts/bio', account: account
 
-      - unless account.fields.empty?
-        .account__header__fields
-          - account.fields.each do |field|
-            %dl
-              %dt.emojify{ title: field.name }= field.name
-              %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value, custom_emojify: true)
-
-    .details-counters
-      .counter{ class: active_nav_class(short_account_url(account)) }
-        = link_to short_account_url(account), class: 'u-url u-uid' do
-          %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
-          %span.counter-label= t('accounts.posts')
-
-      .counter{ class: active_nav_class(account_following_index_url(account)) }
+      .public-account-header__extra__links
         = link_to account_following_index_url(account) do
-          %span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
-          %span.counter-label= t('accounts.following')
-
-      .counter{ class: active_nav_class(account_followers_url(account)) }
+          %strong= number_to_human account.following_count, strip_insignificant_zeros: true
+          = t('accounts.following', count: account.following_count)
         = link_to account_followers_url(account) do
-          %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
-          %span.counter-label= t('accounts.followers')
+          %strong= number_to_human account.followers_count, strip_insignificant_zeros: true
+          = t('accounts.followers', count: account.followers_count)
diff --git a/app/views/accounts/_moved_strip.html.haml b/app/views/accounts/_moved.html.haml
similarity index 52%
rename from app/views/accounts/_moved_strip.html.haml
rename to app/views/accounts/_moved.html.haml
index ae18c6dc70005781babc4ec0f53c71a3f55fe919..7a777bfea84f1c9e1644e4dd198eeaf39d2e502c 100644
--- a/app/views/accounts/_moved_strip.html.haml
+++ b/app/views/accounts/_moved.html.haml
@@ -1,17 +1,18 @@
 - moved_to_account = account.moved_to_account
 
-.moved-strip
-  .moved-strip__message
+.moved-account-widget
+  .moved-account-widget__message
     = fa_icon 'suitcase'
-    = t('accounts.moved_html', name: content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention'))
+    = t('accounts.moved_html', name: content_tag(:bdi, content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify)), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention'))
 
-  .moved-strip__card
-    = link_to TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do
+  .moved-account-widget__card
+    = link_to TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'me noopener' do
       .detailed-status__display-avatar
         .account__avatar-overlay
           .account__avatar-overlay-base{ style: "background-image: url('#{moved_to_account.avatar.url(:original)}')" }
           .account__avatar-overlay-overlay{ style: "background-image: url('#{account.avatar.url(:original)}')" }
 
       %span.display-name
-        %strong.emojify= display_name(moved_to_account, custom_emojify: true)
+        %bdi
+          %strong.emojify= display_name(moved_to_account, custom_emojify: true)
         %span @#{moved_to_account.acct}
diff --git a/app/views/accounts/_nothing_here.html.haml b/app/views/accounts/_nothing_here.html.haml
deleted file mode 100644
index 0c6dc116845f8696e813e02cb3563d50868ad3a7..0000000000000000000000000000000000000000
--- a/app/views/accounts/_nothing_here.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-%p.nothing-here= t('accounts.nothing_here')
diff --git a/app/views/accounts/_og.html.haml b/app/views/accounts/_og.html.haml
index a583b39c2c9db93557e76af7de2dc5b790f7de58..de948ec6ab56cf5237db3f11cfcf8d0d3f9900f0 100644
--- a/app/views/accounts/_og.html.haml
+++ b/app/views/accounts/_og.html.haml
@@ -1,7 +1,11 @@
+- description = account_description(account)
+
+%meta{ name: 'description', content: description }/
+
 = opengraph 'og:url', url
 = opengraph 'og:site_name', site_title
 = opengraph 'og:title', yield(:page_title).strip
-= opengraph 'og:description', account_description(account)
+= opengraph 'og:description', description
 = opengraph 'og:image', full_asset_url(account.avatar.url(:original))
 = opengraph 'og:image:width', '120'
 = opengraph 'og:image:height', '120'
diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml
index cfdd3a9452080a8c59fb81bd01ecdd7a48614321..0ee9dd7deda4dc53a78c899a0fc811b706498d41 100644
--- a/app/views/accounts/show.html.haml
+++ b/app/views/accounts/show.html.haml
@@ -8,8 +8,8 @@
     %meta{ name: 'robots', content: 'noindex' }/
 
   %link{ rel: 'salmon', href: api_salmon_url(@account.id) }/
-  %link{ rel: 'alternate', type: 'application/rss+xml', href: account_url(@account, format: 'rss') }/
   %link{ rel: 'alternate', type: 'application/atom+xml', href: account_url(@account, format: 'atom') }/
+  %link{ rel: 'alternate', type: 'application/rss+xml', href: account_url(@account, format: 'rss') }/
   %link{ rel: 'alternate', type: 'application/activity+json', href: ActivityPub::TagManager.instance.uri_for(@account) }/
 
   - if @older_url
@@ -20,36 +20,47 @@
   = opengraph 'og:type', 'profile'
   = render 'og', account: @account, url: short_account_url(@account, only_path: false)
 
-- if @account.memorial?
-  .memoriam-strip= t('in_memoriam_html')
-- elsif @account.moved?
-  = render partial: 'moved_strip', locals: { account: @account }
-- elsif show_landing_strip?
-  = render partial: 'shared/landing_strip', locals: { account: @account }
-
-.h-feed
-  %data.p-name{ value: "#{@account.username} on #{site_hostname}" }/
-
-  = render 'header', account: @account
-
-  .activity-stream-tabs
-    = active_link_to t('accounts.posts'), short_account_url(@account)
-    = 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?
-    .accounts-grid
-      = render 'nothing_here'
-  - else
-    .activity-stream.with-header
-      - if params[:page].to_i.zero?
-        = render partial: 'stream_entries/status', collection: @pinned_statuses, as: :status, locals: { pinned: true }
-
-      = render partial: 'stream_entries/status', collection: @statuses, as: :status
-
-  - if @newer_url || @older_url
-    .pagination
-      - if @older_url
-        = link_to safe_join([fa_icon('chevron-left'), t('pagination.older')], ' '), @older_url, class: 'older', rel: 'next'
-      - if @newer_url
-        = link_to safe_join([t('pagination.newer'), fa_icon('chevron-right')], ' '), @newer_url, class: 'newer', rel: 'prev'
+
+= render 'header', account: @account, with_bio: true
+
+.grid
+  .column-0
+    .h-feed
+      %data.p-name{ value: "#{@account.username} on #{site_hostname}" }/
+
+      .account__section-headline
+        = active_link_to t('accounts.posts_tab_heading'), short_account_url(@account)
+        = 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?
+        = nothing_here 'nothing-here--under-tabs'
+      - else
+        .activity-stream
+          - if params[:page].to_i.zero?
+            = render partial: 'stream_entries/status', collection: @pinned_statuses, as: :status, locals: { pinned: true }
+
+          - if @newer_url
+            .entry= link_to_more @newer_url
+
+          = render partial: 'stream_entries/status', collection: @statuses, as: :status
+
+          - if @older_url
+            .entry= link_to_more @older_url
+
+  .column-1
+    - if @account.memorial?
+      .memoriam-widget= t('in_memoriam_html')
+    - elsif @account.moved?
+      = render 'moved', account: @account
+
+    = render 'bio', account: @account
+
+    - unless @endorsed_accounts.empty?
+      .endorsements-widget
+        %h4= t 'accounts.choices_html', name: content_tag(:bdi, display_name(@account, custom_emojify: true))
+
+        - @endorsed_accounts.each do |account|
+          = account_link_to account
+
+    = render 'application/sidebar'
diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..97286c8e5b5ef1edd35d7b6ddd14a450d24dce71
--- /dev/null
+++ b/app/views/admin/account_actions/new.html.haml
@@ -0,0 +1,26 @@
+- content_for :page_title do
+  = t('admin.account_actions.title', acct: @account.acct)
+
+= simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f|
+  = f.input :report_id, as: :hidden
+
+  .fields-group
+    = f.input :type, collection: Admin::AccountAction.types_for_account(@account), include_blank: false, wrapper: :with_block_label, label_method: ->(type) { I18n.t("simple_form.labels.admin_account_action.types.#{type}")}, hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.acct)
+
+  - if @account.local?
+    %hr.spacer/
+
+    .fields-group
+      = f.input :send_email_notification, as: :boolean, wrapper: :with_label
+
+    %hr.spacer/
+
+    - unless @warning_presets.empty?
+      .fields-group
+        = f.input :warning_preset_id, collection: @warning_presets, label_method: :text, wrapper: :with_block_label
+
+    .fields-group
+      = f.input :text, as: :text, wrapper: :with_block_label, hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path)
+
+  .actions
+    = f.button :button, t('admin.account_actions.action'), type: :submit
diff --git a/app/views/admin/account_warnings/_account_warning.html.haml b/app/views/admin/account_warnings/_account_warning.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..8c9c9679ceda9fb5d8ed6d4ab31e80bf43541023
--- /dev/null
+++ b/app/views/admin/account_warnings/_account_warning.html.haml
@@ -0,0 +1,6 @@
+.speech-bubble.warning
+  .speech-bubble__bubble
+    = Formatter.instance.linkify(account_warning.text)
+  .speech-bubble__owner
+    = admin_account_link_to account_warning.account
+    %time.formatted{ datetime: account_warning.created_at.iso8601 }= l account_warning.created_at
diff --git a/app/views/admin/accounts/_account.html.haml b/app/views/admin/accounts/_account.html.haml
index c6e63152d5c7d8e3158bc0d9be0cb23a7f09611c..1e1bb1812b0436666a3534444ce8aa8aa291d209 100644
--- a/app/views/admin/accounts/_account.html.haml
+++ b/app/views/admin/accounts/_account.html.haml
@@ -1,18 +1,18 @@
 %tr
-  %td.username
-    = account.username
   %td
-    - unless account.local?
-      = link_to account.domain, admin_accounts_path(by_domain: account.domain)
+    = admin_account_link_to(account)
   %td
-    - if account.local?
-      - if account.user.nil?
-        = t("admin.accounts.moderation.suspended")
-      - else
-        = t("admin.accounts.roles.#{account.user.role}")
+    %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
+    - else
+      \-
+  %td
+    - if account.user_current_sign_in_at
+      %time.time-ago{ datetime: account.user_current_sign_in_at.iso8601, title: l(account.user_current_sign_in_at) }= l account.user_current_sign_in_at
     - else
-      = account.protocol.humanize
+      \-
   %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)
-    = table_link_to 'pencil', t('admin.accounts.edit'), admin_account_path(account.id)
diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
index 6aa39a80a0d92967f21440a45c6cdac8c369d655..91fddadf81d41edb6c626851a29a8b798b70c60a 100644
--- a/app/views/admin/accounts/index.html.haml
+++ b/app/views/admin/accounts/index.html.haml
@@ -5,41 +5,19 @@
   .filter-subset
     %strong= t('admin.accounts.location.title')
     %ul
-      %li= filter_link_to t('admin.accounts.location.all'), local: nil, remote: nil
-      %li
-        - if selected? local: '1', remote: nil
-          = filter_link_to t('admin.accounts.location.local'), {local: nil, remote: nil}, {local: '1', remote: nil}
-        - else
-          = filter_link_to t('admin.accounts.location.local'), local: '1', remote: nil
-      %li
-        - if selected? remote: '1', local: nil
-          = filter_link_to t('admin.accounts.location.remote'), {remote: nil, local: nil}, {remote: '1', local: nil}
-        - else
-          = filter_link_to t('admin.accounts.location.remote'), remote: '1', local: nil
+      %li= filter_link_to t('admin.accounts.location.local'), remote: nil
+      %li= filter_link_to t('admin.accounts.location.remote'), remote: '1'
   .filter-subset
     %strong= t('admin.accounts.moderation.title')
     %ul
-      %li= filter_link_to t('admin.accounts.moderation.all'), silenced: nil, suspended: nil
-      %li
-        - if selected? silenced: '1'
-          = filter_link_to t('admin.accounts.moderation.silenced'), {silenced: nil}, {silenced: '1'}
-        - else
-          = filter_link_to t('admin.accounts.moderation.silenced'), silenced: '1'
-      %li
-        - if selected? suspended: '1'
-          = filter_link_to t('admin.accounts.moderation.suspended'), {suspended: nil}, {suspended: '1'}
-        - else
-          = filter_link_to t('admin.accounts.moderation.suspended'), suspended: '1'
+      %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
   .filter-subset
     %strong= t('admin.accounts.role')
     %ul
       %li= filter_link_to t('admin.accounts.moderation.all'), staff: nil
       %li= filter_link_to t('admin.accounts.roles.staff'), staff: '1'
-  .filter-subset
-    %strong= t('admin.accounts.order.title')
-    %ul
-      %li= filter_link_to t('admin.accounts.order.alphabetic'), recent: nil
-      %li= filter_link_to t('admin.accounts.order.most_recent'), recent: '1'
 
 = form_tag admin_accounts_url, method: 'GET', class: 'simple_form' do
   .fields-group
@@ -60,8 +38,9 @@
     %thead
       %tr
         %th= t('admin.accounts.username')
-        %th= t('admin.accounts.domain')
-        %th
+        %th= t('admin.accounts.role')
+        %th= t('admin.accounts.most_recent_ip')
+        %th= t('admin.accounts.most_recent_activity')
         %th
     %tbody
       = render @accounts
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index ed8190af5af34ec50c4ce24cffbf79a01fbd8eb0..280a834ba268d0ae2da9b188f1ee1b77dffe2c6c 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -1,189 +1,185 @@
 - content_for :page_title do
   = @account.acct
 
-.table-wrapper
-  %table.table.inline-table
-    %tbody
-      %tr
-        %th= t('admin.accounts.username')
-        %td= @account.username
-      %tr
-        %th= t('admin.accounts.domain')
-        %td= @account.domain
-      %tr
-        %th= t('admin.accounts.display_name')
-        %td= @account.display_name
-
-      %tr
-        %th= t('admin.accounts.avatar')
-        %th
-          = link_to @account.avatar.url(:original) do
-            = image_tag @account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar'
-          - if @account.local? && @account.avatar?
-            = table_link_to 'trash', t('admin.accounts.remove_avatar'), remove_avatar_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:remove_avatar, @account)
-
-      - if @account.local?
-        %tr
-          %th= t('admin.accounts.role')
-          %td
-            - if @account.user.nil?
-              = t("admin.accounts.moderation.suspended")
-            - else
-              = t("admin.accounts.roles.#{@account.user&.role}")
-            = table_link_to 'angle-double-up', t('admin.accounts.promote'), promote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:promote, @account.user)
-            = table_link_to 'angle-double-down', t('admin.accounts.demote'), demote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:demote, @account.user)
-        %tr
-          %th= t('admin.accounts.email')
-          %td
-            = @account.user_email
-            = table_link_to 'edit', t('admin.accounts.change_email.label'), admin_account_change_email_path(@account.id) if can?(:change_email, @account.user)
-        - if @account.user_unconfirmed_email.present?
-          %th= t('admin.accounts.unconfirmed_email')
-          %td
-            = @account.user_unconfirmed_email
-        %tr
-          %th= t('admin.accounts.email_status')
-          %td
-            - if @account.user&.confirmed?
-              = t('admin.accounts.confirmed')
-            - else
-              = t('admin.accounts.confirming')
-              = table_link_to 'refresh', t('admin.accounts.resend_confirmation.send'), resend_admin_account_confirmation_path(@account.id), method: :post if can?(:confirm, @account.user)
-        %tr
-          %th= t('admin.accounts.login_status')
-          %td
-            - if @account.user&.disabled?
-              = t('admin.accounts.disabled')
-              = table_link_to 'unlock', t('admin.accounts.enable'), enable_admin_account_path(@account.id), method: :post if can?(:enable, @account.user)
-            - else
-              = t('admin.accounts.enabled')
-              = table_link_to 'lock', t('admin.accounts.disable'), disable_admin_account_path(@account.id), method: :post if can?(:disable, @account.user)
-        %tr
-          %th= t('admin.accounts.most_recent_ip')
-          %td= @account.user_current_sign_in_ip
-        %tr
-          %th= t('admin.accounts.most_recent_activity')
-          %td
-            - if @account.user_current_sign_in_at
-              %time.formatted{ datetime: @account.user_current_sign_in_at.iso8601, title: l(@account.user_current_sign_in_at) }
-                = l @account.user_current_sign_in_at
-            - else
-              Never
-      - else
-        %tr
-          %th= t('admin.accounts.profile_url')
-          %td= link_to @account.url, @account.url
-        %tr
-          %th= t('admin.accounts.protocol')
-          %td= @account.protocol.humanize
-
-      %tr
-        %th= t('admin.accounts.follows')
-        %td= number_to_human @account.following_count
-      %tr
-        %th= t('admin.accounts.followers')
-        %td= number_to_human @account.followers_count
-      %tr
-        %th= t('admin.accounts.statuses')
-        %td= link_to number_to_human(@account.statuses_count), admin_account_statuses_path(@account.id)
-      %tr
-        %th= t('admin.accounts.media_attachments')
-        %td
-          = link_to number_to_human(@account.media_attachments.count), admin_account_statuses_path(@account.id, { media: true })
-          = surround '(', ')' do
-            = number_to_human_size @account.media_attachments.sum('file_file_size')
-      %tr
-        %th= t('.created_reports')
-        %td= link_to pluralize(@account.reports.count, t('.report')), admin_reports_path(account_id: @account.id)
-      %tr
-        %th= t('.targeted_reports')
-        %td= link_to pluralize(@account.targeted_reports.count, t('.report')), admin_reports_path(target_account_id: @account.id)
-
-%div{ style: 'overflow: hidden' }
-  %div{ style: 'float: right' }
-    - if @account.local?
-      = 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?
-        = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' 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.silenced?
-      = link_to t('admin.accounts.undo_silenced'), admin_account_silence_path(@account.id), method: :delete, class: 'button' if can?(:unsilence, @account)
-    - else
-      = link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button' if can?(:silence, @account)
-
-    - if @account.local?
-      - 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'), admin_account_suspension_path(@account.id), method: :delete, class: 'button' if can?(:unsuspend, @account)
-    - else
-      = link_to t('admin.accounts.perform_full_suspension'), admin_account_suspension_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:suspend, @account)
-
-- if !@account.local? && @account.hub_url.present?
-  %hr.spacer/
-
-  %h3 OStatus
-
+= render 'application/card', account: @account
+
+.dashboard__counters{ style: 'margin-top: 10px' }
+  %div
+    = link_to admin_account_statuses_path(@account.id) do
+      .dashboard__counters__num= number_with_delimiter @account.statuses_count
+      .dashboard__counters__label= t 'admin.accounts.statuses'
+  %div
+    = link_to admin_account_statuses_path(@account.id, { media: true }) do
+      .dashboard__counters__num= number_to_human_size @account.media_attachments.sum('file_file_size')
+      .dashboard__counters__label= t 'admin.accounts.media_attachments'
+  %div
+    = link_to admin_account_followers_path(@account.id) do
+      .dashboard__counters__num= number_with_delimiter @account.local_followers_count
+      .dashboard__counters__label= t 'admin.accounts.followers'
+  %div
+    = link_to admin_reports_path(account_id: @account.id) do
+      .dashboard__counters__num= number_with_delimiter @account.reports.count
+      .dashboard__counters__label= t '.created_reports'
+  %div
+    = link_to admin_reports_path(target_account_id: @account.id) do
+      .dashboard__counters__num= number_with_delimiter @account.targeted_reports.count
+      .dashboard__counters__label= t '.targeted_reports'
+  %div
+    %div
+      .dashboard__counters__text
+        - if @account.local? && @account.user.nil?
+          %span.neutral= t('admin.accounts.deleted')
+        - elsif @account.suspended?
+          %span.red= t('admin.accounts.suspended')
+        - elsif @account.silenced?
+          %span.red= t('admin.accounts.silenced')
+        - elsif @account.local? && @account.user&.disabled?
+          %span.red= t('admin.accounts.disabled')
+        - elsif @account.local? && !@account.user&.confirmed?
+          %span.neutral= t('admin.accounts.confirming')
+        - else
+          %span.neutral= t('admin.accounts.no_limits_imposed')
+      .dashboard__counters__label= t 'admin.accounts.login_status'
+
+- unless @account.local? && @account.user.nil?
   .table-wrapper
     %table.table.inline-table
       %tbody
-        %tr
-          %th= t('admin.accounts.feed_url')
-          %td= link_to @account.remote_url, @account.remote_url
-        %tr
-          %th= t('admin.accounts.push_subscription_expires')
-          %td
-            - if @account.subscribed?
-              %time.formatted{ datetime: @account.subscription_expires_at.iso8601, title: l(@account.subscription_expires_at) }
-                = l @account.subscription_expires_at
-            - else
-              = t('admin.accounts.not_subscribed')
-        %tr
-          %th= t('admin.accounts.salmon_url')
-          %td= link_to @account.salmon_url, @account.salmon_url
+        - if @account.local?
+          - if @account.avatar?
+            %tr
+              %th= t('admin.accounts.avatar')
+              %td= table_link_to 'trash', t('admin.accounts.remove_avatar'), remove_avatar_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:remove_avatar, @account)
+              %td
+
+          - if @account.header?
+            %tr
+              %th= t('admin.accounts.header')
+              %td= table_link_to 'trash', t('admin.accounts.remove_header'), remove_header_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:remove_header, @account)
+              %td
+
+          %tr
+            %th= t('admin.accounts.role')
+            %td= t("admin.accounts.roles.#{@account.user&.role}")
+            %td
+              = table_link_to 'angle-double-up', t('admin.accounts.promote'), promote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:promote, @account.user)
+              = table_link_to 'angle-double-down', t('admin.accounts.demote'), demote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:demote, @account.user)
+
+          %tr
+            %th= t('admin.accounts.email')
+            %td= @account.user_email
+            %td= table_link_to 'edit', t('admin.accounts.change_email.label'), admin_account_change_email_path(@account.id) if can?(:change_email, @account.user)
+
+          - if @account.user_unconfirmed_email.present?
+            %tr
+              %th= t('admin.accounts.unconfirmed_email')
+              %td= @account.user_unconfirmed_email
+              %td
+
+          %tr
+            %th= t('admin.accounts.email_status')
+            %td
+              - if @account.user&.confirmed?
+                = t('admin.accounts.confirmed')
+              - else
+                = t('admin.accounts.confirming')
+            %td= table_link_to 'refresh', t('admin.accounts.resend_confirmation.send'), resend_admin_account_confirmation_path(@account.id), method: :post if can?(:confirm, @account.user)
+
+          %tr
+            %th= t('admin.accounts.login_status')
+            %td
+              - if @account.user&.disabled?
+                = t('admin.accounts.disabled')
+              - else
+                = t('admin.accounts.enabled')
+            %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
+                = table_link_to 'lock', t('admin.accounts.disable'), new_admin_account_action_path(@account.id, type: 'disable') if can?(:disable, @account.user)
+
+          %tr
+            %th= t('simple_form.labels.defaults.locale')
+            %td= @account.user_locale
+            %td
+
+          %tr
+            %th= t('admin.accounts.joined')
+            %td
+              %time.formatted{ datetime: @account.created_at.iso8601, title: l(@account.created_at) }= l @account.created_at
+            %td
+
+          %tr
+            %th= t('admin.accounts.most_recent_ip')
+            %td= @account.user_current_sign_in_ip
+            %td
+
+          %tr
+            %th= t('admin.accounts.most_recent_activity')
+            %td
+              - if @account.user_current_sign_in_at
+                %time.formatted{ datetime: @account.user_current_sign_in_at.iso8601, title: l(@account.user_current_sign_in_at) }= l @account.user_current_sign_in_at
+
+          - if @account.user&.invited?
+            %tr
+              %th= t('admin.accounts.invited_by')
+              %td= admin_account_link_to @account.user.invite.user.account
+              %td
+
+        - else
+          %tr
+            %th= t('admin.accounts.inbox_url')
+            %td
+              = @account.inbox_url
+              = fa_icon DeliveryFailureTracker.unavailable?(@account.inbox_url) ? 'times' : 'check'
+          %tr
+            %th= t('admin.accounts.shared_inbox_url')
+            %td
+              = @account.shared_inbox_url
+              = fa_icon DeliveryFailureTracker.unavailable?(@account.shared_inbox_url) ? 'times' : 'check'
 
   %div{ style: 'overflow: hidden' }
     %div{ style: 'float: right' }
-      = link_to @account.subscribed? ? t('admin.accounts.resubscribe') : t('admin.accounts.subscribe'), subscribe_admin_account_path(@account.id), method: :post, class: 'button' if can?(:subscribe, @account)
-      - if @account.subscribed?
-        = link_to t('admin.accounts.unsubscribe'), unsubscribe_admin_account_path(@account.id), method: :post, class: 'button negative' if can?(:unsubscribe, @account)
+      - if @account.local?
+        = 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?
+          = 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?
+        = 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
+        = 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?
+        - 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
+        = 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)
 
-- if !@account.local? && @account.inbox_url.present?
   %hr.spacer/
 
-  %h3 ActivityPub
+  - unless @warnings.empty?
+    = render @warnings
 
-  .table-wrapper
-    %table.table.inline-table
-      %tbody
-        %tr
-          %th= t('admin.accounts.inbox_url')
-          %td= link_to @account.inbox_url, @account.inbox_url
-        %tr
-          %th= t('admin.accounts.outbox_url')
-          %td= link_to @account.outbox_url, @account.outbox_url
-        %tr
-          %th= t('admin.accounts.shared_inbox_url')
-          %td= link_to @account.shared_inbox_url, @account.shared_inbox_url
-        %tr
-          %th= t('admin.accounts.followers_url')
-          %td= link_to @account.followers_url, @account.followers_url
-
-%hr.spacer/
-
-= render @moderation_notes
-
-= simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |f|
-  = render 'shared/error_messages', object: @account_moderation_note
-
-  = f.input :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6
-  = f.hidden_field :target_account_id
-
-  .actions
-    = f.button :button, t('admin.account_moderation_notes.create'), type: :submit
+    %hr.spacer/
+
+  = render @moderation_notes
+
+  = simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |f|
+    = render 'shared/error_messages', object: @account_moderation_note
+
+    = f.input :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6
+    = f.hidden_field :target_account_id
+
+    .actions
+      = f.button :button, t('admin.account_moderation_notes.create'), type: :submit
diff --git a/app/views/admin/change_emails/show.html.haml b/app/views/admin/change_emails/show.html.haml
index a661b1ad618e31d3b3b41b2e093945ad1093b69f..6febef9b1a811abdd045cf22b50cdaf6ded699d9 100644
--- a/app/views/admin/change_emails/show.html.haml
+++ b/app/views/admin/change_emails/show.html.haml
@@ -2,6 +2,11 @@
   = t('admin.accounts.change_email.title', username: @account.acct)
 
 = simple_form_for @user, url: admin_account_change_email_path(@account.id) do |f|
-  = f.input :email, wrapper: :with_label, disabled: true, label: t('admin.accounts.change_email.current_email')
-  = f.input :unconfirmed_email, wrapper: :with_label, label: t('admin.accounts.change_email.new_email')
-  = f.button :submit, class: "button", value: t('admin.accounts.change_email.submit')
+  .fields-group
+    = f.input :email, wrapper: :with_label, 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')
+
+  .actions
+    = f.button :submit, class: "button", value: t('admin.accounts.change_email.submit')
diff --git a/app/views/admin/custom_emojis/new.html.haml b/app/views/admin/custom_emojis/new.html.haml
index 672afe435fc85f9d466c8f1c0550810c776d74f2..e15a07cb8146c7b819a36223bd8e70f512f72f3b 100644
--- a/app/views/admin/custom_emojis/new.html.haml
+++ b/app/views/admin/custom_emojis/new.html.haml
@@ -5,8 +5,9 @@
   = render 'shared/error_messages', object: @custom_emoji
 
   .fields-group
-    = f.input :shortcode, placeholder: t('admin.custom_emojis.shortcode'), hint: t('admin.custom_emojis.shortcode_hint')
-    = f.input :image, input_html: { accept: 'image/png' }, hint: t('admin.custom_emojis.image_hint')
+    = f.input :shortcode, wrapper: :with_label, label: t('admin.custom_emojis.shortcode'), hint: t('admin.custom_emojis.shortcode_hint')
+  .fields-group
+    = f.input :image, wrapper: :with_label, input_html: { accept: 'image/png' }, hint: t('admin.custom_emojis.image_hint')
 
   .actions
     = f.button :button, t('admin.custom_emojis.upload'), type: :submit
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..fa3d70e9eddd4b45d5bd53ffedc55926c595f1e0
--- /dev/null
+++ b/app/views/admin/dashboard/index.html.haml
@@ -0,0 +1,155 @@
+- content_for :page_title do
+  = t('admin.dashboard.title')
+
+.dashboard__counters
+  %div
+    = link_to admin_accounts_url(local: 1, recent: 1) do
+      .dashboard__counters__num= number_with_delimiter @users_count
+      .dashboard__counters__label= t 'admin.dashboard.total_users'
+  %div
+    %div
+      .dashboard__counters__num= number_with_delimiter @registrations_week
+      .dashboard__counters__label= t 'admin.dashboard.week_users_new'
+  %div
+    %div
+      .dashboard__counters__num= number_with_delimiter @logins_week
+      .dashboard__counters__label= t 'admin.dashboard.week_users_active'
+  %div
+    %div
+      .dashboard__counters__num= number_with_delimiter @interactions_week
+      .dashboard__counters__label= t 'admin.dashboard.week_interactions'
+  %div
+    = link_to admin_reports_url do
+      .dashboard__counters__num= number_with_delimiter @reports_count
+      .dashboard__counters__label= t 'admin.dashboard.open_reports'
+  %div
+    = link_to sidekiq_url do
+      .dashboard__counters__num= number_with_delimiter @queue_backlog
+      .dashboard__counters__label= t 'admin.dashboard.backlog'
+
+.dashboard__widgets
+  .dashboard__widgets__users
+    %div
+      %h4= t 'admin.dashboard.recent_users'
+      %ul
+        - @recent_users.each do |user|
+          %li= admin_account_link_to(user.account)
+
+  .dashboard__widgets__features
+    %div
+      %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'
+
+  .dashboard__widgets__versions
+    %div
+      %h4= t 'admin.dashboard.software'
+      %ul
+        %li
+          Mastodon
+          %span.pull-right= @version
+        %li
+          Ruby
+          %span.pull-right= "#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
+        %li
+          PostgreSQL
+          %span.pull-right= @database_version
+        %li
+          Redis
+          %span.pull-right= @redis_version
+
+  .dashboard__widgets__space
+    %div
+      %h4= t 'admin.dashboard.space'
+      %ul
+        %li
+          PostgreSQL
+          %span.pull-right= number_to_human_size @database_size
+        %li
+          Redis
+          %span.pull-right= number_to_human_size @redis_size
+
+  .dashboard__widgets__config
+    %div
+      %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'
+
+  .dashboard__widgets__trends
+    %div
+      %h4= t 'admin.dashboard.trends'
+      %ul
+        - @trending_hashtags.each do |tag|
+          %li
+            = link_to "##{tag.name}", web_url("timelines/tag/#{tag.name}")
+            %span.pull-right= number_with_delimiter(tag.history[0][:accounts].to_i)
diff --git a/app/views/admin/domain_blocks/_domain_block.html.haml b/app/views/admin/domain_blocks/_domain_block.html.haml
deleted file mode 100644
index 17a3de81c64314d4fb933af19765137cf258bbb1..0000000000000000000000000000000000000000
--- a/app/views/admin/domain_blocks/_domain_block.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-%tr
-  %td.domain
-    %samp= domain_block.domain
-  %td.severity
-    = t("admin.domain_blocks.severities.#{domain_block.severity}")
-  %td.reject_media
-    - if domain_block.reject_media? || domain_block.suspend?
-      %i.fa.fa-check
-  %td
-    = table_link_to 'undo', t('admin.domain_blocks.undo'), admin_domain_block_path(domain_block)
diff --git a/app/views/admin/domain_blocks/index.html.haml b/app/views/admin/domain_blocks/index.html.haml
deleted file mode 100644
index 42b8ca53f484fa2af4527c14c0f9f8094635334a..0000000000000000000000000000000000000000
--- a/app/views/admin/domain_blocks/index.html.haml
+++ /dev/null
@@ -1,16 +0,0 @@
-- content_for :page_title do
-  = t('admin.domain_blocks.title')
-
-.table-wrapper
-  %table.table
-    %thead
-      %tr
-        %th= t('admin.domain_blocks.domain')
-        %th= t('admin.domain_blocks.severity')
-        %th= t('admin.domain_blocks.reject_media')
-        %th
-    %tbody
-      = render @domain_blocks
-
-= paginate @domain_blocks
-= link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path, class: 'button'
diff --git a/app/views/admin/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml
index 38fa9016905a9d5e4ba1d0e0dd51a43ce61f7e07..055d2fbd7e44dc81cb490ccbb64d7ec4844b238a 100644
--- a/app/views/admin/domain_blocks/new.html.haml
+++ b/app/views/admin/domain_blocks/new.html.haml
@@ -1,17 +1,24 @@
+- content_for :header_tags do
+  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+
 - content_for :page_title do
   = t('.title')
 
 = simple_form_for @domain_block, url: admin_domain_blocks_path do |f|
   = render 'shared/error_messages', object: @domain_block
 
-  %p.hint= t('.hint')
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :domain, wrapper: :with_label, label: t('admin.domain_blocks.domain'), hint: t('.hint'), required: true
 
-  = f.input :domain, placeholder: t('admin.domain_blocks.domain')
-  = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| t(".severity.#{type}") }
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| t(".severity.#{type}") }, hint: t('.severity.desc_html')
 
-  %p.hint= t('.severity.desc_html')
+  .fields-group
+    = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint')
 
-  = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint')
+  .fields-group
+    = f.input :reject_reports, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reports'), hint: I18n.t('admin.domain_blocks.reject_reports_hint')
 
   .actions
     = f.button :button, t('.create'), type: :submit
diff --git a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
index 61cff93955f7e6f13684970a8d362ea54442ac9f..bf66c9001da4b3c15b3724fc38967351d41094f5 100644
--- a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
+++ b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
@@ -1,5 +1,5 @@
 %tr
-  %td.domain
+  %td
     %samp= email_domain_block.domain
   %td
     = table_link_to 'trash', t('admin.email_domain_blocks.delete'), admin_email_domain_block_path(email_domain_block), method: :delete
diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml
index bcae867d957b9e3dd1c5b799779ff3aab84ead75..f372fa51200676b544b40229c931ca8d9d40d631 100644
--- a/app/views/admin/email_domain_blocks/new.html.haml
+++ b/app/views/admin/email_domain_blocks/new.html.haml
@@ -4,7 +4,8 @@
 = simple_form_for @email_domain_block, url: admin_email_domain_blocks_path do |f|
   = render 'shared/error_messages', object: @email_domain_block
 
-  = f.input :domain, placeholder: t('admin.email_domain_blocks.domain')
+  .fields-group
+    = f.input :domain, wrapper: :with_label, label: t('admin.email_domain_blocks.domain')
 
   .actions
     = f.button :button, t('.create'), type: :submit
diff --git a/app/views/admin/followers/index.html.haml b/app/views/admin/followers/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..25f1f290f42686a741a6ff0a5a7731520a31d618
--- /dev/null
+++ b/app/views/admin/followers/index.html.haml
@@ -0,0 +1,28 @@
+- content_for :page_title do
+  = t('admin.followers.title', acct: @account.acct)
+
+.filters
+  .filter-subset
+    %strong= t('admin.accounts.location.title')
+    %ul
+      %li= link_to t('admin.accounts.location.local'), admin_account_followers_path(@account.id), class: 'selected'
+  .back-link{ style: 'flex: 1 1 auto; text-align: right' }
+    = link_to admin_account_path(@account.id) do
+      = fa_icon 'chevron-left fw'
+      = t('admin.followers.back_to_account')
+
+%hr.spacer/
+
+.table-wrapper
+  %table.table
+    %thead
+      %tr
+        %th= t('admin.accounts.username')
+        %th= t('admin.accounts.role')
+        %th= t('admin.accounts.most_recent_ip')
+        %th= t('admin.accounts.most_recent_activity')
+        %th
+    %tbody
+      = render partial: 'admin/accounts/account', collection: @followers
+
+= paginate @followers
diff --git a/app/views/admin/instances/_instance.html.haml b/app/views/admin/instances/_instance.html.haml
deleted file mode 100644
index 6efbbbe60a56a969ccc150339d3f9a63991d05c2..0000000000000000000000000000000000000000
--- a/app/views/admin/instances/_instance.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-%tr
-  %td.domain
-    = link_to instance.domain, admin_accounts_path(by_domain: instance.domain)
-  %td.count
-    = instance.accounts_count
-  %td
-    = table_link_to 'paper-plane-o', t('admin.accounts.resubscribe'), resubscribe_admin_instances_url(by_domain: instance.domain), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml
index 3314ce07789e0159b15d711baa7e2b1f7b83c8ec..ce35b5db4751ade39b32b4e7f17798b9cd611710 100644
--- a/app/views/admin/instances/index.html.haml
+++ b/app/views/admin/instances/index.html.haml
@@ -1,23 +1,39 @@
 - content_for :page_title do
   = t('admin.instances.title')
 
-= form_tag admin_instances_url, method: 'GET', class: 'simple_form' do
-  .fields-group
-    - %i(domain_name).each do |key|
-      .input.string.optional
-        = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.instances.#{key}")
+.filters
+  .filter-subset
+    %strong= t('admin.instances.moderation.title')
+    %ul
+      %li= filter_link_to t('admin.instances.moderation.all'), limited: nil
+      %li= filter_link_to t('admin.instances.moderation.limited'), limited: '1'
 
-    .actions
-      %button= t('admin.instances.search')
-      = link_to t('admin.instances.reset'), admin_instances_path, class: 'button negative'
+  %div{ style: 'flex: 1 1 auto; text-align: right' }
+    = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path, class: 'button'
 
-.table-wrapper
-  %table.table
-    %thead
-      %tr
-        %th= t('admin.instances.domain_name')
-        %th= t('admin.instances.account_count')
-    %tbody
-      = render @instances
+%hr.spacer/
+
+- @instances.each do |instance|
+  .directory__tag
+    = link_to admin_instance_path(instance) do
+      %h4
+        = instance.domain
+        %small
+          = t('admin.instances.known_accounts', count: instance.accounts_count)
+
+          - if instance.domain_block
+            - if !instance.domain_block.noop?
+              &bull;
+              = t("admin.domain_blocks.severity.#{instance.domain_block.severity}")
+            - if instance.domain_block.reject_media?
+              &bull;
+              = t('admin.domain_blocks.rejecting_media')
+            - if instance.domain_block.reject_reports?
+              &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'
 
 = paginate paginated_instances
diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..c7992a490d09b576e8cc9bf595bfbc9cbdcfda86
--- /dev/null
+++ b/app/views/admin/instances/show.html.haml
@@ -0,0 +1,44 @@
+- content_for :page_title do
+  = @instance.domain
+
+.dashboard__counters
+  %div
+    %div
+      .dashboard__counters__num= number_with_delimiter @following_count
+      .dashboard__counters__label= t 'admin.instances.total_followed_by_them'
+  %div
+    %div
+      .dashboard__counters__num= number_with_delimiter @followers_count
+      .dashboard__counters__label= t 'admin.instances.total_followed_by_us'
+  %div
+    %div
+      .dashboard__counters__num= number_to_human_size @media_storage
+      .dashboard__counters__label= t 'admin.instances.total_storage'
+  %div
+    %div
+      .dashboard__counters__num= number_with_delimiter @blocks_count
+      .dashboard__counters__label= t 'admin.instances.total_blocked_by_us'
+  %div
+    %div
+      .dashboard__counters__num= number_with_delimiter @reports_count
+      .dashboard__counters__label= t 'admin.instances.total_reported'
+  %div
+    %div
+      .dashboard__counters__num
+        - if @available
+          = fa_icon 'check'
+        - else
+          = fa_icon 'times'
+      .dashboard__counters__label= t 'admin.instances.delivery_available'
+
+%hr.spacer/
+
+%div{ style: 'overflow: hidden' }
+  %div{ style: 'float: left' }
+    = link_to t('admin.accounts.title'), admin_accounts_path(remote: '1', by_domain: @instance.domain), class: 'button'
+
+  %div{ style: 'float: right' }
+    - if @domain_block
+      = link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@domain_block), class: 'button'
+    - else
+      = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button'
diff --git a/app/views/admin/invites/index.html.haml b/app/views/admin/invites/index.html.haml
index 944a6047141b8f3651c87b28a9383a3fc6a4b7d9..42159e9f36750429856bfcba7de82aa8afb6ba66 100644
--- a/app/views/admin/invites/index.html.haml
+++ b/app/views/admin/invites/index.html.haml
@@ -9,22 +9,28 @@
       %li= filter_link_to t('admin.invites.filter.available'), available: 1, expired: nil
       %li= filter_link_to t('admin.invites.filter.expired'), available: nil, expired: 1
 
+%hr.spacer/
+
 - if policy(:invite).create?
   %p= t('invites.prompt')
 
   = render 'invites/form'
 
-  %hr/
+  %hr.spacer/
 
-%table.table
-  %thead
-    %tr
-      %th
-      %th= t('invites.table.uses')
-      %th= t('invites.table.expires_at')
-      %th
-      %th
-  %tbody
-    = render @invites
+.table-wrapper
+  %table.table
+    %thead
+      %tr
+        %th
+        %th= t('invites.table.uses')
+        %th= t('invites.table.expires_at')
+        %th
+        %th
+    %tbody
+      = render @invites
 
 = paginate @invites
+
+- if policy(:invite).deactivate_all?
+  = link_to t('admin.invites.deactivate_all'), deactivate_all_admin_invites_path, method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button'
diff --git a/app/views/admin/relays/_relay.html.haml b/app/views/admin/relays/_relay.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..6678218947e609d88056823ce889c601888304aa
--- /dev/null
+++ b/app/views/admin/relays/_relay.html.haml
@@ -0,0 +1,25 @@
+%tr
+  %td
+    %samp= relay.inbox_url
+  %td
+    - if relay.accepted?
+      %span.positive-hint
+        = fa_icon('check')
+        = ' '
+        = t 'admin.relays.enabled'
+    - elsif relay.pending?
+      = fa_icon('hourglass')
+      = ' '
+      = t 'admin.relays.pending'
+    - else
+      %span.negative-hint
+        = fa_icon('times')
+        = ' '
+        = t 'admin.relays.disabled'
+  %td
+    - if relay.accepted?
+      = table_link_to 'power-off', t('admin.relays.disable'), disable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
+    - elsif !relay.pending?
+      = table_link_to 'power-off', t('admin.relays.enable'), enable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
+
+    = table_link_to 'times', t('admin.relays.delete'), admin_relay_path(relay), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/admin/relays/index.html.haml b/app/views/admin/relays/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..1636a53f8521df4b1a9f2b23b683632ef3b44315
--- /dev/null
+++ b/app/views/admin/relays/index.html.haml
@@ -0,0 +1,20 @@
+- content_for :page_title do
+  = t('admin.relays.title')
+
+.simple_form
+  %p.hint= t('admin.relays.description_html')
+  = link_to @relays.empty? ? t('admin.relays.setup') : t('admin.relays.add_new'), new_admin_relay_path, class: 'block-button'
+
+- unless @relays.empty?
+  %hr.spacer
+
+  .table-wrapper
+    %table.table
+      %thead
+        %tr
+          %th= t('admin.relays.inbox_url')
+          %th= t('admin.relays.status')
+          %th
+      %tbody
+        = render @relays
+
diff --git a/app/views/admin/relays/new.html.haml b/app/views/admin/relays/new.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..126794acfe5a3833940e40e2b2e2f1712b69e863
--- /dev/null
+++ b/app/views/admin/relays/new.html.haml
@@ -0,0 +1,13 @@
+- content_for :page_title do
+  = t('admin.relays.add_new')
+
+= simple_form_for @relay, url: admin_relays_path do |f|
+  = render 'shared/error_messages', object: @relay
+
+  .field-group
+    = f.input :inbox_url, as: :string, wrapper: :with_block_label
+
+  .actions
+    = f.button :button, t('admin.relays.save_and_enable'), type: :submit
+
+  %p.hint.subtle-hint= t('admin.relays.enable_hint')
diff --git a/app/views/admin/reports/_account.html.haml b/app/views/admin/reports/_account.html.haml
deleted file mode 100644
index 9ac161c9c6980a1c565628e6d34f45f19f0f7dee..0000000000000000000000000000000000000000
--- a/app/views/admin/reports/_account.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-- size ||= 36
-
-.account.compact
-  .account__wrapper
-    - if account.nil?
-      .account__display-name
-        .account__avatar-wrapper
-          .account__avatar{ style: "background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)}); width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px" }
-        %span.display-name
-          %strong= t 'about.contact_missing'
-          %span.display-name__account= t 'about.contact_unavailable'
-    - else
-      = link_to TagManager.instance.url_for(account), class: 'account__display-name' do
-        .account__avatar-wrapper
-          .account__avatar{ style: "background-image: url(#{account.avatar.url}); width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px" }
-        %span.display-name
-          %bdi
-            %strong.display-name__html.emojify= display_name(account, custom_emojify: true)
-          %span.display-name__account @#{account.acct}
diff --git a/app/views/admin/reports/_report.html.haml b/app/views/admin/reports/_report.html.haml
deleted file mode 100644
index 7b25c924bc9a18bff51ff52399ff15704c5501e9..0000000000000000000000000000000000000000
--- a/app/views/admin/reports/_report.html.haml
+++ /dev/null
@@ -1,29 +0,0 @@
-%tr
-  %td.id
-    = "##{report.id}"
-  %td.target
-    = admin_account_link_to report.target_account
-  %td.reporter
-    - if report.account.local?
-      = admin_account_link_to report.account
-    - else
-      = report.account.domain
-  %td
-    %div{ title: report.comment }
-      = truncate(report.comment, length: 30, separator: ' ')
-    %div
-      - unless report.statuses.empty?
-        %span{ title: t('admin.accounts.statuses') }
-          = fa_icon('comment')
-          = report.statuses.count
-      - unless report.media_attachments.empty?
-        %span{ title: t('admin.accounts.media_attachments') }
-          = fa_icon('camera')
-          = report.media_attachments.count
-  %td
-    - if report.assigned_account.nil?
-      \-
-    - else
-      = admin_account_link_to report.assigned_account
-  %td
-    = table_link_to 'circle', t('admin.reports.view'), admin_report_path(report)
diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml
index 5e174f312ec1c3b34c830e6d9fd7287485cde862..b3c145120a08c555365167ef80f4b60b1c0b6f8f 100644
--- a/app/views/admin/reports/_status.html.haml
+++ b/app/views/admin/reports/_status.html.haml
@@ -3,18 +3,20 @@
     = f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id
   .batch-table__row__content
     .status__content><
-      - unless status.proper.spoiler_text.blank?
-        %p><
-          %strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)}
-
-      = Formatter.instance.format(status.proper, custom_emojify: true)
+      - if status.proper.spoiler_text.blank?
+        = Formatter.instance.format(status.proper, custom_emojify: true)
+      - else
+        %details<
+          %summary><
+            %strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)}
+          = Formatter.instance.format(status.proper, custom_emojify: true)
 
     - unless status.proper.media_attachments.empty?
       - if status.proper.media_attachments.first.video?
         - video = status.proper.media_attachments.first
-        = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
+        = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: !current_account&.user&.show_all_media? && status.proper.sensitive? || current_account&.user&.hide_all_media?, width: 610, height: 343, inline: true, alt: video.description
       - else
-        = react_component :media_gallery, height: 343, sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
+        = 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, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
 
     .detailed-status__meta
       = link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener' do
diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml
index 44a531f2c66c2c17db1995195e560c02af1718ad..d73faccb0d9d971b6c4a8144bfdb95f9e9e0ae01 100644
--- a/app/views/admin/reports/index.html.haml
+++ b/app/views/admin/reports/index.html.haml
@@ -8,17 +8,45 @@
       %li= filter_link_to t('admin.reports.unresolved'), resolved: nil
       %li= filter_link_to t('admin.reports.resolved'), resolved: '1'
 
-.table-wrapper
-  %table.table
-    %thead
-      %tr
-        %th= t('admin.reports.id')
-        %th= t('admin.reports.target')
-        %th= t('admin.reports.reported_by')
-        %th= t('admin.reports.report_contents')
-        %th= t('admin.reports.assigned')
-        %th
-    %tbody
-      = render @reports
+- @reports.group_by(&:target_account_id).each do |target_account_id, reports|
+  - target_account = reports.first.target_account
+  .report-card
+    .report-card__profile
+      = account_link_to target_account, '', size: 36, path: admin_account_path(target_account.id)
+      .report-card__profile__stats
+        = link_to pluralize(target_account.targeted_moderation_notes.count, t('admin.reports.account.note')), admin_account_path(target_account.id)
+        %br/
+        - if target_account.suspended?
+          %span.red= t('admin.accounts.suspended')
+        - elsif target_account.silenced?
+          %span.red= t('admin.accounts.silenced')
+        - elsif target_account.user&.disabled?
+          %span.red= t('admin.accounts.disabled')
+        - else
+          %span.neutral= t('admin.accounts.no_limits_imposed')
+    .report-card__summary
+      - reports.each do |report|
+        .report-card__summary__item
+          .report-card__summary__item__reported-by
+            - if report.account.local?
+              = admin_account_link_to report.account
+            - else
+              = report.account.domain
+          .report-card__summary__item__content
+            = link_to admin_report_path(report) do
+              .one-line= report.comment.presence || t('admin.reports.comment.none')
 
+              %span.report-card__summary__item__content__icon{ title: t('admin.accounts.statuses') }
+                = fa_icon('comment')
+                = report.statuses.count
+
+              %span.report-card__summary__item__content__icon{ title: t('admin.accounts.media_attachments') }
+                = fa_icon('camera')
+                = report.media_attachments.count
+
+          .report-card__summary__item__assigned
+            - if report.assigned_account.present?
+              = admin_account_link_to report.assigned_account
+            - else
+              \-
 = paginate @reports
diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml
index b13bb530350f7c3d36bf7eb824f3b19feb8a7102..863dada9e27c1e5acc9bbe5b462705e777e97087 100644
--- a/app/views/admin/reports/show.html.haml
+++ b/app/views/admin/reports/show.html.haml
@@ -7,12 +7,15 @@
 %div{ style: 'overflow: hidden; margin-bottom: 20px' }
   - if @report.unresolved?
     %div{ style: 'float: right' }
-      = link_to t('admin.reports.silence_account'), admin_report_path(@report, outcome: 'silence'), method: :put, class: 'button'
-      = link_to t('admin.reports.suspend_account'), admin_report_path(@report, outcome: 'suspend'), method: :put, class: 'button'
+      - if @report.target_account.local?
+        = link_to t('admin.accounts.warn'), new_admin_account_action_path(@report.target_account_id, type: 'none', report_id: @report.id), class: 'button'
+        = link_to t('admin.accounts.disable'), new_admin_account_action_path(@report.target_account_id, type: 'disable', report_id: @report.id), class: 'button button--destructive'
+      = link_to t('admin.accounts.silence'), new_admin_account_action_path(@report.target_account_id, type: 'silence', report_id: @report.id), class: 'button button--destructive'
+      = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@report.target_account_id, type: 'suspend', report_id: @report.id), class: 'button button--destructive'
     %div{ style: 'float: left' }
-      = link_to t('admin.reports.mark_as_resolved'), admin_report_path(@report, outcome: 'resolve'), method: :put, class: 'button'
+      = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button'
   - else
-    = link_to t('admin.reports.mark_as_unresolved'), admin_report_path(@report, outcome: 'reopen'), method: :put, class: 'button'
+    = link_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), method: :post, class: 'button'
 
 %hr.spacer
 
@@ -65,10 +68,10 @@
               = admin_account_link_to @report.assigned_account
           %td
             - if @report.assigned_account != current_user.account
-              = table_link_to 'user', t('admin.reports.assign_to_self'), admin_report_path(@report, outcome: 'assign_to_self'), method: :put
+              = table_link_to 'user', t('admin.reports.assign_to_self'), assign_to_self_admin_report_path(@report), method: :post
           %td
             - if !@report.assigned_account.nil?
-              = table_link_to 'trash', t('admin.reports.unassign'), admin_report_path(@report, outcome: 'unassign'), method: :put
+              = table_link_to 'trash', t('admin.reports.unassign'), unassign_admin_report_path(@report), method: :post
 
 %hr.spacer
 
@@ -102,7 +105,7 @@
 - @report_notes.each do |item|
   - if item.is_a?(Admin::ActionLog)
     = render partial: 'action_log', locals: { action_log: item }
-  - elsif item.is_a?(ReportNote)
+  - else
     = render item
 
 = simple_form_for @report_note, url: admin_report_notes_path do |f|
diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml
index f5c5deca850d97084ebb993c540db7c1eef4e564..7afa9ec3718df12ab521d70a448aeb0067595b01 100644
--- a/app/views/admin/settings/edit.html.haml
+++ b/app/views/admin/settings/edit.html.haml
@@ -2,22 +2,41 @@
   = t('admin.settings.title')
 
 = simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch } do |f|
-  .actions.actions--top
-    = f.button :button, t('generic.save_changes'), type: :submit
 
   .fields-group
-    = f.input :site_title, placeholder: t('admin.settings.site_title')
-    = f.input :site_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description.title'), hint: t('admin.settings.site_description.desc_html'), input_html: { rows: 8 }
-    = f.input :site_contact_username, placeholder: t('admin.settings.contact_information.username')
-    = f.input :site_contact_email, placeholder: t('admin.settings.contact_information.email')
+    = 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 :site_contact_username, wrapper: :with_label, label: t('admin.settings.contact_information.username')
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :site_contact_email, wrapper: :with_label, label: t('admin.settings.contact_information.email')
 
-  %hr/
+  .fields-group
+    = f.input :site_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description.title'), hint: t('admin.settings.site_description.desc_html'), input_html: { rows: 4 }
 
   .fields-group
-    = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: t('admin.settings.thumbnail.desc_html')
-    = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: t('admin.settings.hero.desc_html')
+    = f.input :site_short_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_short_description.title'), hint: t('admin.settings.site_short_description.desc_html'), input_html: { rows: 2 }
+
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: t('admin.settings.thumbnail.desc_html')
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: t('admin.settings.hero.desc_html')
 
-  %hr/
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :mascot, as: :file, wrapper: :with_block_label, label: t('admin.settings.mascot.title'), hint: t('admin.settings.mascot.desc_html')
+
+  %hr.spacer/
+
+  .fields-group
+    = f.input :bootstrap_timeline_accounts, wrapper: :with_block_label, label: t('admin.settings.bootstrap_timeline_accounts.title'), hint: t('admin.settings.bootstrap_timeline_accounts.desc_html')
+
+  %hr.spacer/
 
   .fields-group
     = f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html')
@@ -35,34 +54,27 @@
     = f.input :open_deletion, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.deletion.title'), hint: t('admin.settings.registrations.deletion.desc_html')
 
   .fields-group
-    = f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 }
-
-  %hr/
+    = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html')
 
   .fields-group
-    = f.input :min_invite_role, wrapper: :with_label, collection: %i(disabled user moderator admin), label: t('admin.settings.registrations.min_invite_role.title'), label_method: lambda { |role| role == :disabled ? t('admin.settings.registrations.min_invite_role.disabled') : t("admin.accounts.roles.#{role}") }, as: :radio_buttons, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
-
-  %hr/
+    = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.peers_api_enabled.title'), hint: t('admin.settings.peers_api_enabled.desc_html')
 
   .fields-group
-    = f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 }
-    = f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 }
-
-  %hr/
+    = f.input :preview_sensitive_media, as: :boolean, wrapper: :with_label, label: t('admin.settings.preview_sensitive_media.title'), hint: t('admin.settings.preview_sensitive_media.desc_html')
 
   .fields-group
-    = f.input :bootstrap_timeline_accounts, wrapper: :with_block_label, label: t('admin.settings.bootstrap_timeline_accounts.title'), hint: t('admin.settings.bootstrap_timeline_accounts.desc_html')
-
-  %hr/
+    = f.input :profile_directory, as: :boolean, wrapper: :with_label, label: t('admin.settings.profile_directory.title'), hint: t('admin.settings.profile_directory.desc_html')
 
-  .fields-group
-    = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html')
+  %hr.spacer/
 
   .fields-group
-    = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.peers_api_enabled.title'), hint: t('admin.settings.peers_api_enabled.desc_html')
+    = f.input :min_invite_role, wrapper: :with_label, collection: %i(disabled user moderator admin), label: t('admin.settings.registrations.min_invite_role.title'), label_method: lambda { |role| role == :disabled ? t('admin.settings.registrations.min_invite_role.disabled') : t("admin.accounts.roles.#{role}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
 
   .fields-group
-    = f.input :preview_sensitive_media, as: :boolean, wrapper: :with_label, label: t('admin.settings.preview_sensitive_media.title'), hint: t('admin.settings.preview_sensitive_media.desc_html')
+    = f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 }
+    = f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 }
+    = f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 }
+    = f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }, label: t('admin.settings.custom_css.title'), hint: t('admin.settings.custom_css.desc_html')
 
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/admin/statuses/index.html.haml b/app/views/admin/statuses/index.html.haml
index 880a24f7692a214f6307f382f9a128c42b10782d..dd3c798150e25c827c5929828d64f66df329d22e 100644
--- a/app/views/admin/statuses/index.html.haml
+++ b/app/views/admin/statuses/index.html.haml
@@ -14,7 +14,7 @@
       %li= link_to t('admin.statuses.with_media'), admin_account_statuses_path(@account.id, current_params.merge(media: true)), class: params[:media] && 'selected'
   .back-link{ style: 'flex: 1 1 auto; text-align: right' }
     = link_to admin_account_path(@account.id) do
-      %i.fa.fa-chevron-left.fa-fw
+      = fa_icon 'chevron-left fw'
       = t('admin.statuses.back_to_account')
 
 %hr.spacer/
diff --git a/app/views/admin/statuses/show.html.haml b/app/views/admin/statuses/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..a7a392272fc25c7f5901abdc9af6fefac9e769e2
--- /dev/null
+++ b/app/views/admin/statuses/show.html.haml
@@ -0,0 +1,27 @@
+- content_for :page_title do
+  = t('admin.statuses.title')
+  \-
+  = "@#{@account.acct}"
+
+.filters
+  .back-link{ style: 'flex: 1 1 auto; text-align: right' }
+    = link_to admin_account_path(@account.id) do
+      %i.fa.fa-chevron-left.fa-fw
+      = t('admin.statuses.back_to_account')
+
+%hr.spacer/
+
+= form_for(@form, url: admin_account_statuses_path(@account.id)) do |f|
+  = hidden_field_tag :page, params[:page]
+  = hidden_field_tag :media, params[:media]
+
+  .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('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
+        = f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
+        = f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
+    .batch-table__body
+      = render partial: 'admin/reports/status', collection: @statuses, locals: { f: f }
diff --git a/app/views/admin/tags/_tag.html.haml b/app/views/admin/tags/_tag.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..961b83f93c23c1b4f1d235e390d50eb284db3c44
--- /dev/null
+++ b/app/views/admin/tags/_tag.html.haml
@@ -0,0 +1,12 @@
+%tr
+  %td
+    = link_to explore_hashtag_path(tag) do
+      = fa_icon 'hashtag'
+      = tag.name
+  %td
+    = t('directories.people', count: tag.accounts_count)
+  %td
+    - if tag.hidden?
+      = table_link_to 'eye', t('admin.tags.unhide'), unhide_admin_tag_path(tag.id, **@filter_params), method: :post
+    - else
+      = table_link_to 'eye-slash', t('admin.tags.hide'), hide_admin_tag_path(tag.id, **@filter_params), method: :post
diff --git a/app/views/admin/tags/index.html.haml b/app/views/admin/tags/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..4ba3958605d69e1d989ce05bc83417f824010d0a
--- /dev/null
+++ b/app/views/admin/tags/index.html.haml
@@ -0,0 +1,19 @@
+- content_for :page_title do
+  = t('admin.tags.title')
+
+.filters
+  .filter-subset
+    %strong= t('admin.reports.status')
+    %ul
+      %li= filter_link_to t('admin.tags.visible'), hidden: nil
+      %li= filter_link_to t('admin.tags.hidden'), hidden: '1'
+
+.table-wrapper
+  %table.table
+    %thead
+      %tr
+        %th= t('admin.tags.name')
+        %th= t('admin.tags.accounts')
+        %th
+    %tbody
+      = render @tags
diff --git a/app/views/admin/warning_presets/edit.html.haml b/app/views/admin/warning_presets/edit.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..9522746cd11c4c077d8e80d2f8cd76063d8777d8
--- /dev/null
+++ b/app/views/admin/warning_presets/edit.html.haml
@@ -0,0 +1,11 @@
+- content_for :page_title do
+  = t('admin.warning_presets.edit_preset')
+
+= simple_form_for @warning_preset, url: admin_warning_preset_path(@warning_preset) do |f|
+  = render 'shared/error_messages', object: @warning_preset
+
+  .fields-group
+    = f.input :text, wrapper: :with_block_label
+
+  .actions
+    = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/admin/warning_presets/index.html.haml b/app/views/admin/warning_presets/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..45913ef73384382d83ec3424728134cf8d0ef6a5
--- /dev/null
+++ b/app/views/admin/warning_presets/index.html.haml
@@ -0,0 +1,30 @@
+- content_for :page_title do
+  = t('admin.warning_presets.title')
+
+- if can? :create, :account_warning_preset
+  = simple_form_for @warning_preset, url: admin_warning_presets_path do |f|
+    = render 'shared/error_messages', object: @warning_preset
+
+    .fields-group
+      = f.input :text, wrapper: :with_block_label
+
+    .actions
+      = f.button :button, t('admin.warning_presets.add_new'), type: :submit
+
+  %hr.spacer/
+
+- unless @warning_presets.empty?
+  .table-wrapper
+    %table.table
+      %thead
+        %tr
+          %th= t('simple_form.labels.account_warning_preset.text')
+          %th
+      %tbody
+        - @warning_presets.each do |preset|
+          %tr
+            %td
+              = Formatter.instance.linkify(preset.text)
+            %td
+              = table_link_to 'pencil', t('admin.warning_presets.edit'), edit_admin_warning_preset_path(preset)
+              = table_link_to 'trash', t('admin.warning_presets.delete'), admin_warning_preset_path(preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/application/_card.html.haml b/app/views/application/_card.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..e6059b03507aa0e7322474cbd973f263fe0ac59b
--- /dev/null
+++ b/app/views/application/_card.html.haml
@@ -0,0 +1,17 @@
+- account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account)
+
+.card.h-card
+  = link_to account_url, target: '_blank', rel: 'noopener' do
+    .card__img
+      = image_tag account.header.url, alt: ''
+    .card__bar
+      .avatar
+        = image_tag account.avatar.url, alt: '', width: 48, height: 48, class: 'u-photo'
+
+      .display-name
+        %span{id: "default_account_display_name", style: "display:none;"}= account.username
+        %bdi
+          %strong.emojify.p-name= display_name(account, custom_emojify: true)
+        %span
+          = acct(account)
+          = fa_icon('lock') if account.locked?
diff --git a/app/views/application/_sidebar.html.haml b/app/views/application/_sidebar.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..2ff14b2526fed39494e7f090143dc6f4ad080772
--- /dev/null
+++ b/app/views/application/_sidebar.html.haml
@@ -0,0 +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
+
+  .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/confirmations/finish_signup.html.haml b/app/views/auth/confirmations/finish_signup.html.haml
index 4b5161d6b05fa14ec589fb00348cacdd39804efc..9d09b74e1627515eed3641c78374041ddcdd36af 100644
--- a/app/views/auth/confirmations/finish_signup.html.haml
+++ b/app/views/auth/confirmations/finish_signup.html.haml
@@ -8,7 +8,8 @@
         = msg
         %br
 
-  = f.input :email
+  .fields-group
+    = f.input :email, wrapper: :with_label, required: true, hint: false
 
   .actions
     = f.submit t('auth.confirm_email'), class: 'button'
diff --git a/app/views/auth/confirmations/new.html.haml b/app/views/auth/confirmations/new.html.haml
index 07ca4a7da900aa09f1ed698ceff0f6bb5bb3c0df..4a1bedaa4231644c1490ba067e2662861549a9f2 100644
--- a/app/views/auth/confirmations/new.html.haml
+++ b/app/views/auth/confirmations/new.html.haml
@@ -4,7 +4,8 @@
 = simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
   = render 'shared/error_messages', object: resource
 
-  = f.input :email, autofocus: true, required: true, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
+  .fields-group
+    = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
 
   .actions
     = f.button :button, t('auth.resend_confirmation'), type: :submit
diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml
index 53d1769d623a0f9681e2573f60f90ccd5540b596..383d44f00fa3f9ae49109f2c7e9b2ddf40d09bbe 100644
--- a/app/views/auth/passwords/edit.html.haml
+++ b/app/views/auth/passwords/edit.html.haml
@@ -7,8 +7,10 @@
   - if !use_seamless_external_login? || resource.encrypted_password.present?
     = f.input :reset_password_token, as: :hidden
 
-    = f.input :password, autofocus: true, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
-    = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
+    .fields-group
+      = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }, required: true
+    .fields-group
+      = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }, required: true
 
     .actions
       = f.button :button, t('auth.set_new_password'), type: :submit
diff --git a/app/views/auth/passwords/new.html.haml b/app/views/auth/passwords/new.html.haml
index f4d22031a5ab65730bba31b13451333607b5e5aa..bae5b24ba8fe5175d9ec29627b10c3d6cdf980c4 100644
--- a/app/views/auth/passwords/new.html.haml
+++ b/app/views/auth/passwords/new.html.haml
@@ -4,7 +4,8 @@
 = simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
   = render 'shared/error_messages', object: resource
 
-  = f.input :email, autofocus: true, required: true, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
+  .fields-group
+    = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
 
   .actions
     = f.button :button, t('auth.reset_password'), type: :submit
diff --git a/app/views/auth/registrations/_sessions.html.haml b/app/views/auth/registrations/_sessions.html.haml
index 8586c0549573fb9a65159c13e34a84680d4b5d71..d7d96a1bb3338617854e9063e5b88eb344142187 100644
--- a/app/views/auth/registrations/_sessions.html.haml
+++ b/app/views/auth/registrations/_sessions.html.haml
@@ -8,7 +8,7 @@
         %th= t 'sessions.browser'
         %th= t 'sessions.ip'
         %th= t 'sessions.activity'
-        %td
+        %th
     %tbody
       - @sessions.each do |session|
         %tr
diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml
index 05fc7df313bc99738e67a595d8db55b1781ddb0d..694461fdf2ec4f71161201e20e010e08ca5bbece 100644
--- a/app/views/auth/registrations/edit.html.haml
+++ b/app/views/auth/registrations/edit.html.haml
@@ -1,24 +1,33 @@
 - content_for :page_title do
   = t('auth.security')
 
-%h4= t('auth.change_password')
 = simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: 'auth_edit' }) do |f|
   = render 'shared/error_messages', object: resource
 
   - if !use_seamless_external_login? || resource.encrypted_password.present?
-    = f.input :email, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
-    = f.input :password, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
-    = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
-    = f.input :current_password, placeholder: t('simple_form.labels.defaults.current_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'off' }
+    .fields-group
+      = f.input :email, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, required: true, hint: false
+
+    .fields-group
+      = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'off' }, required: true
+
+    .fields-group
+      = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }, hint: false
+
+    .fields-group
+      = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
+
 
     .actions
       = f.button :button, t('generic.save_changes'), type: :submit
   - else
     %p.hint= t('users.seamless_external_login')
 
+%hr.spacer/
+
 = render 'sessions'
 
 - if open_deletion?
-
+  %hr.spacer/
   %h4= t('auth.delete_account')
   %p.muted-hint= t('auth.delete_account_html', path: settings_delete_path)
diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml
index 0fac8e10da121576ea9c9072bbc9b9dbddd867fd..72ce8e531fc322789a52f3b2dcd1343e83ea9cb0 100644
--- a/app/views/auth/registrations/new.html.haml
+++ b/app/views/auth/registrations/new.html.haml
@@ -10,21 +10,25 @@
   - if @invite.present? && @invite.autofollow?
     .fields-group{ style: 'margin-bottom: 30px' }
       %p.hint{ style: 'text-align: center' }= t('invites.invited_by')
-      = render 'authorize_follows/card', account: @invite.user.account
+      = render 'application/card', account: @invite.user.account
 
   = f.simple_fields_for :account do |ff|
-    .input-with-append
-      = ff.input :username, autofocus: true, placeholder: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off' }
-      .append
-        = "@#{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' }
-  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
-  = 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' }
+    .fields-group
+      = ff.input :username, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off' }, append: "@#{site_hostname}", hint: t('simple_form.hints.defaults.username', domain: site_hostname)
+
+  .fields-group
+    = f.input :email, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }
+
+  .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' }
+
   = f.input :invite_code, as: :hidden
 
+  %p.hint= t('auth.agreement_html', rules_path: about_more_path, terms_path: terms_path)
+
   .actions
     = f.button :button, t('auth.register'), type: :submit
 
-  %p.hint.subtle-hint=t('auth.agreement_html', rules_path: about_more_path, terms_path: terms_path)
 .form-footer= render 'auth/shared/links'
diff --git a/app/views/auth/sessions/new.html.haml b/app/views/auth/sessions/new.html.haml
index 0c9f9d5fe8fa9cfc40d0c60a9f88ba529e4a05d0..ceb1694084bee70ebe50a7cfdb41623d6282465f 100644
--- a/app/views/auth/sessions/new.html.haml
+++ b/app/views/auth/sessions/new.html.haml
@@ -5,11 +5,13 @@
   = render partial: 'shared/og'
 
 = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
-  - if use_seamless_external_login?
-    = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.username_or_email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }
-  - else
-    = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
-  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
+  .fields-group
+    - if use_seamless_external_login?
+      = f.input :email, autofocus: true, wrapper: :with_label, label: 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, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
+  .fields-group
+    = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }, hint: false
 
   .actions
     = f.button :button, t('auth.login'), type: :submit
diff --git a/app/views/auth/sessions/two_factor.html.haml b/app/views/auth/sessions/two_factor.html.haml
index 1af3193ae0e58d8688a1b8df3fe253ec1c24e043..4e6bbd7a9583c58c4a6183718739bec4f053fa26 100644
--- a/app/views/auth/sessions/two_factor.html.haml
+++ b/app/views/auth/sessions/two_factor.html.haml
@@ -4,7 +4,8 @@
 = simple_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
   %p.hint{ style: 'margin-bottom: 25px' }= t('simple_form.hints.sessions.otp')
 
-  = f.input :otp_attempt, type: :number, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'off' }, required: true, autofocus: true
+  .fields-group
+    = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'off' }, autofocus: true
 
   .actions
     = f.button :button, t('auth.login'), type: :submit
diff --git a/app/views/auth/shared/_links.html.haml b/app/views/auth/shared/_links.html.haml
index 08b38509272f1bac46290669edd0e3d73cdffde2..516c625a6b564cfe2877e77c377dab80802c1b8d 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'), new_registration_path(resource_name)
+    %li= link_to t('auth.register'), open_registrations? ? new_registration_path(resource_name) : 'https://joinmastodon.org/#getting-started'
 
   - 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/authorize_follows/_card.html.haml b/app/views/authorize_follows/_card.html.haml
deleted file mode 100644
index edc03131f4b4cc1bbed4b3cfd67d7ae487ff3582..0000000000000000000000000000000000000000
--- a/app/views/authorize_follows/_card.html.haml
+++ /dev/null
@@ -1,23 +0,0 @@
-.account-card
-  .account-card__header{ style: "background-image: url(#{account.header.url(:original)})" }
-  .detailed-status__display-name
-    %div
-      = image_tag account.avatar.url(:original), alt: '', width: 48, height: 48, class: 'avatar'
-
-    %span.display-name
-      - account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account)
-      = link_to account_url, class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do
-        %strong.emojify= display_name(account, custom_emojify: true)
-        %span @#{account.acct}
-
-    .counter
-      %span.counter-number= number_to_human account.statuses_count, strip_insignificant_zeros: true
-      %span.counter-label= t('accounts.posts')
-
-    .counter
-      %span.counter-number= number_to_human account.following_count, strip_insignificant_zeros: true
-      %span.counter-label= t('accounts.following')
-
-    .counter
-      %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true
-      %span.counter-label= t('accounts.followers')
diff --git a/app/views/authorize_follows/show.html.haml b/app/views/authorize_follows/show.html.haml
deleted file mode 100644
index a1fd01dd6b7b4dbfcdf30c466fb9c8fa83f611b3..0000000000000000000000000000000000000000
--- a/app/views/authorize_follows/show.html.haml
+++ /dev/null
@@ -1,17 +0,0 @@
-- content_for :page_title do
-  = t('authorize_follow.title', acct: @account.acct)
-
-.form-container
-  .follow-prompt
-    = render 'card', account: @account
-
-  - if current_account.following?(@account)
-    .flash-message
-      %strong
-        = t('authorize_follow.already_following')
-    = render 'post_follow_actions'
-
-  - else
-    = form_tag authorize_follow_path, method: :post, class: 'simple_form' do
-      = hidden_field_tag :acct, @account.acct
-      = button_tag t('authorize_follow.follow'), type: :submit
diff --git a/app/views/authorize_follows/_post_follow_actions.html.haml b/app/views/authorize_interactions/_post_follow_actions.html.haml
similarity index 61%
rename from app/views/authorize_follows/_post_follow_actions.html.haml
rename to app/views/authorize_interactions/_post_follow_actions.html.haml
index 2a9c062e9c78e3a4975e390ddef01f6a5bf57bc8..561c60137fc4ac7a01f201499297fd73555b7fe7 100644
--- a/app/views/authorize_follows/_post_follow_actions.html.haml
+++ b/app/views/authorize_interactions/_post_follow_actions.html.haml
@@ -1,4 +1,4 @@
 .post-follow-actions
-  %div= link_to t('authorize_follow.post_follow.web'), web_url("accounts/#{@account.id}"), class: 'button button--block'
-  %div= link_to t('authorize_follow.post_follow.return'), TagManager.instance.url_for(@account), class: 'button button--block'
+  %div= link_to t('authorize_follow.post_follow.web'), web_url("accounts/#{@resource.id}"), class: 'button button--block'
+  %div= link_to t('authorize_follow.post_follow.return'), TagManager.instance.url_for(@resource), class: 'button button--block'
   %div= t('authorize_follow.post_follow.close')
diff --git a/app/views/authorize_follows/error.html.haml b/app/views/authorize_interactions/error.html.haml
similarity index 100%
rename from app/views/authorize_follows/error.html.haml
rename to app/views/authorize_interactions/error.html.haml
diff --git a/app/views/authorize_interactions/show.html.haml b/app/views/authorize_interactions/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..7ca9b98c1b8cc2a65bd622b0d35a2fb29260eabc
--- /dev/null
+++ b/app/views/authorize_interactions/show.html.haml
@@ -0,0 +1,18 @@
+- content_for :page_title do
+  = t('authorize_follow.title', acct: @resource.acct)
+
+.form-container
+  .follow-prompt
+    = render 'application/card', account: @resource
+
+  - if current_account.following?(@resource)
+    .flash-message
+      %strong
+        = t('authorize_follow.already_following')
+
+    = render 'post_follow_actions'
+  - else
+    = form_tag authorize_interaction_path, method: :post, class: 'simple_form' do
+      = hidden_field_tag :action, :follow
+      = hidden_field_tag :acct, @resource.acct
+      = button_tag t('authorize_follow.follow'), type: :submit
diff --git a/app/views/authorize_follows/success.html.haml b/app/views/authorize_interactions/success.html.haml
similarity index 60%
rename from app/views/authorize_follows/success.html.haml
rename to app/views/authorize_interactions/success.html.haml
index fa59b24b8e038b79db452c7edcddd0be7592128c..47fd09767c6afd26dab6cf5cf03d5c91382eee3a 100644
--- a/app/views/authorize_follows/success.html.haml
+++ b/app/views/authorize_interactions/success.html.haml
@@ -1,13 +1,13 @@
 - content_for :page_title do
-  = t('authorize_follow.title', acct: @account.acct)
+  = t('authorize_follow.title', acct: @resource.acct)
 
 .form-container
   .follow-prompt
-    - if @account.locked?
+    - if @resource.locked?
       %h2= t('authorize_follow.follow_request')
     - else
       %h2= t('authorize_follow.following')
 
-    = render 'card', account: @account
+    = render 'application/card', account: @resource
 
   = render 'post_follow_actions'
diff --git a/app/views/directories/index.html.haml b/app/views/directories/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..a8aa68cc434e1e6c1d35fa25d0c03e9c276f5b2a
--- /dev/null
+++ b/app/views/directories/index.html.haml
@@ -0,0 +1,71 @@
+- content_for :page_title do
+  = t('directories.explore_mastodon', title: site_title)
+
+- content_for :header_tags do
+  %meta{ name: 'description', content: t('directories.explanation') }
+
+  = opengraph 'og:site_name', t('about.hosted_on', domain: site_hostname)
+  = opengraph 'og:type', 'website'
+  = opengraph 'og:title', t('directories.explore_mastodon', title: site_title)
+  = opengraph 'og:description', t('directories.explanation')
+  = opengraph 'og:image', File.join(root_url, 'android-chrome-192x192.png')
+
+.page-header
+  %h1= t('directories.explore_mastodon', title: site_title)
+  %p= t('directories.explanation')
+
+.grid
+  .column-0
+    - if @accounts.empty?
+      = nothing_here
+    - else
+      .directory
+        %table.accounts-table
+          %tbody
+            - @accounts.each do |account|
+              %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')
+
+      = paginate @accounts
+
+  .column-1
+    - if user_signed_in?
+      .box-widget.notice-widget
+        - if current_account.discoverable?
+          - if current_account.followers_count < Account::MIN_FOLLOWERS_DISCOVERY
+            %p= t('directories.enabled_but_waiting', min_followers: Account::MIN_FOLLOWERS_DISCOVERY)
+          - else
+            %p= t('directories.enabled')
+        - else
+          %p= t('directories.how_to_enable')
+
+          = link_to settings_profile_path do
+            = t('settings.edit_profile')
+            = fa_icon 'chevron-right fw'
+
+    - if @tags.empty? && !user_signed_in?
+      .nothing-here
+    - else
+      - @tags.each do |tag|
+        .directory__tag{ class: tag.id == @tag&.id ? 'active' : nil }
+          = link_to explore_hashtag_path(tag) do
+            %h4
+              = fa_icon 'hashtag'
+              = tag.name
+              %small= t('directories.people', count: tag.accounts_count)
+
+            .avatar-stack
+              - tag.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'
diff --git a/app/views/filters/_fields.html.haml b/app/views/filters/_fields.html.haml
index a5a3f03375dc5866bec420e5af1a2d4f257740ba..fb94a07fce2a8bb4805aa1037058005497c62f78 100644
--- a/app/views/filters/_fields.html.haml
+++ b/app/views/filters/_fields.html.haml
@@ -1,14 +1,16 @@
-.fields-group
-  = f.input :phrase, as: :string, wrapper: :with_block_label
+.fields-row
+  .fields-row__column.fields-row__column-6.fields-group
+    = f.input :phrase, as: :string, wrapper: :with_label, hint: false
+  .fields-row__column.fields-row__column-6.fields-group
+    = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
 
 .fields-group
   = f.input :context, wrapper: :with_block_label, collection: CustomFilter::VALID_CONTEXTS, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', label_method: lambda { |context| I18n.t("filters.contexts.#{context}") }, include_blank: false
 
+%hr.spacer/
+
 .fields-group
   = f.input :irreversible, wrapper: :with_label
 
 .fields-group
   = f.input :whole_word, wrapper: :with_label
-
-.fields-group
-  = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
diff --git a/app/views/follower_accounts/index.html.haml b/app/views/follower_accounts/index.html.haml
index 65af81a5b70276f01edb6e8a182f4d467c1d7c7e..31dab68bf57c144a8eb4932e11cc83ac2df56a24 100644
--- a/app/views/follower_accounts/index.html.haml
+++ b/app/views/follower_accounts/index.html.haml
@@ -8,6 +8,11 @@
 = render 'accounts/header', account: @account
 
 - if @account.user_hides_network?
-  = render 'accounts/follow_grid_hidden'
+  .nothing-here= t('accounts.network_hidden')
+- elsif @follows.empty?
+  = nothing_here
 - else
-  = render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:account)
+  .card-grid
+    = render partial: 'application/card', collection: @follows.map(&:account), as: :account
+
+  = paginate @follows
diff --git a/app/views/following_accounts/index.html.haml b/app/views/following_accounts/index.html.haml
index 8fd95a0b4da43ac954cc9e6c1bf9c5f85630f790..8b49b529b4d91a159c0822d74d6f11d252d7b81a 100644
--- a/app/views/following_accounts/index.html.haml
+++ b/app/views/following_accounts/index.html.haml
@@ -8,6 +8,11 @@
 = render 'accounts/header', account: @account
 
 - if @account.user_hides_network?
-  = render 'accounts/follow_grid_hidden'
+  .nothing-here= t('accounts.network_hidden')
+- elsif @follows.empty?
+  = nothing_here
 - else
-  = render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:target_account)
+  .card-grid
+    = render partial: 'application/card', collection: @follows.map(&:target_account), as: :account
+
+  = paginate @follows
diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml
index 7b1a7e50aea4fa348fbcb56ffa0ebc3757955299..6f3a6942e93d85a565cd830d500596304927eadc 100644
--- a/app/views/home/index.html.haml
+++ b/app/views/home/index.html.haml
@@ -14,4 +14,4 @@
     = image_tag asset_pack_path('logo.svg'), alt: 'Mastodon'
 
     %div
-      = t('errors.noscript_html')
+      = t('errors.noscript_html', apps_path: 'https://joinmastodon.org/apps')
diff --git a/app/views/invites/_form.html.haml b/app/views/invites/_form.html.haml
index 42a107bb2c139ed8700c6de9b7534bd602490b2a..3a2a5ef0e1c78d64a84d92fdb361ad43f0bcc105 100644
--- a/app/views/invites/_form.html.haml
+++ b/app/views/invites/_form.html.haml
@@ -1,9 +1,11 @@
 = simple_form_for(@invite, url: controller.is_a?(Admin::InvitesController) ? admin_invites_path : invites_path) do |f|
   = render 'shared/error_messages', object: @invite
 
-  .fields-group
-    = f.input :max_uses, wrapper: :with_label, collection: [1, 5, 10, 25, 50, 100], label_method: lambda { |num| I18n.t('invites.max_uses', count: num) }, prompt: I18n.t('invites.max_uses_prompt')
-    = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :max_uses, wrapper: :with_label, collection: [1, 5, 10, 25, 50, 100], label_method: lambda { |num| I18n.t('invites.max_uses', count: num) }, prompt: I18n.t('invites.max_uses_prompt')
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
 
   .fields-group
     = f.input :autofollow, wrapper: :with_label
diff --git a/app/views/invites/index.html.haml b/app/views/invites/index.html.haml
index f4c5047fa0670fba9ba404275d30c559a526dff1..fb827f6e6d0b55f331d09e6341d3105d3909b807 100644
--- a/app/views/invites/index.html.haml
+++ b/app/views/invites/index.html.haml
@@ -6,7 +6,7 @@
 
   = render 'form'
 
-  %hr/
+  %hr.spacer/
 
 %table.table
   %thead
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index c98d85f7bfe7ec38d50b58cc4cb54be9d7c55c1c..6ce67d91e7059d4019f405ba93910a27e2a6904e 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -17,4 +17,4 @@
 
         = yield
 
-= render template: 'layouts/application', locals: { body_classes: 'admin' }
+= render template: 'layouts/application'
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index a903b865bca76e7f74459c693bc8659dc2b51bbf..d0f50c8e9bcfe32db8fe4af20ac893092b54acc3 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -3,6 +3,13 @@
   %head
     %meta{ charset: 'utf-8' }/
     %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1' }/
+
+    - if cdn_host?
+      %link{ rel: 'dns-prefetch', href: cdn_host }/
+
+    - if storage_host?
+      %link{ rel: 'dns-prefetch', href: storage_host }/
+
     %link{ rel: 'icon', href: favicon_path, type: 'image/x-icon' }/
     %link{ rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }/
     %link{ rel: 'mask-icon', href: '/mask-icon.svg', color: '#2B90D9' }/
@@ -20,11 +27,10 @@
     = javascript_pack_tag "locale_#{I18n.locale}", integrity: true, crossorigin: 'anonymous'
     = csrf_meta_tags
 
-    = yield :header_tags
+    - if Setting.custom_css.present?
+      = stylesheet_link_tag custom_css_path, media: 'all'
 
-  - body_classes ||= @body_classes || ''
-  - body_classes += ' system-font' if current_account&.user&.setting_system_font_ui
-  - body_classes += current_account&.user&.setting_reduce_motion ? ' reduce-motion' : ' no-reduce-motion'
+    = yield :header_tags
 
-  %body{ class: add_rtl_body_class(body_classes) }
+  %body{ class: body_classes }
     = content_for?(:content) ? yield(:content) : yield
diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml
index ac11cfbe72e4e9ce9eb857ece4e06f1a98f01dbe..0503dcdc101a47dd25bfb4d3b50d79acaa4689cc 100644
--- a/app/views/layouts/embedded.html.haml
+++ b/app/views/layouts/embedded.html.haml
@@ -4,6 +4,12 @@
     %meta{ charset: 'utf-8' }/
     %meta{ name: 'robots', content: 'noindex' }/
 
+    - if cdn_host?
+      %link{ rel: 'dns-prefetch', href: cdn_host }/
+
+    - if storage_host?
+      %link{ rel: 'dns-prefetch', href: storage_host }/
+
     = stylesheet_pack_tag 'common', media: 'all'
     = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all'
     = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
diff --git a/app/views/layouts/modal.html.haml b/app/views/layouts/modal.html.haml
index 325b4ec726282696f1ffd4febedc998ba7903a20..2ef49e413208ad2e9fa717f4a53d8675a0884e0a 100644
--- a/app/views/layouts/modal.html.haml
+++ b/app/views/layouts/modal.html.haml
@@ -2,13 +2,13 @@
   = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
 
 - content_for :content do
-  - if user_signed_in?
+  - if user_signed_in? && !@hide_header
     .account-header
       .avatar= image_tag current_account.avatar.url(:original)
       .name
         = t 'users.signed_in_as'
         %span.username @#{current_account.local_username_and_domain}
-      = link_to destroy_user_session_path, method: :delete, class: 'logout-link icon-button' do
+      = link_to destroy_user_session_path(continue: true), method: :delete, class: 'logout-link icon-button' do
         = fa_icon 'sign-out'
 
   .container-alt= yield
diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml
index 600290297dc57d6dbf97be48e85b4d0bec55fabc..caccd5bb67f66a7875c351562d68f2a5ad60d1a6 100644
--- a/app/views/layouts/public.html.haml
+++ b/app/views/layouts/public.html.haml
@@ -2,16 +2,54 @@
   = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
 
 - content_for :content do
-  .container-alt= yield
-  .footer
-    - if !user_signed_in? && single_user_mode?
-      %span.single-user-login
-        = link_to t('auth.login'), new_user_session_path
-        &mdash;
-      %span.footer__domain= link_to site_hostname, about_path
-    - else
-      %span.footer__domain= link_to site_hostname, root_path
-    %span.powered-by
-      != t('generic.powered_by', link: link_to('https://joinmastodon.org') { image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon' })
+  .public-layout
+    .container
+      %nav.header
+        .nav-left
+          = link_to root_url, class: 'brand' do
+            = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+
+          - 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'
+
+    .container= yield
+
+    .container
+      .footer
+        .grid
+          .column-0
+            %h4= t 'footer.resources'
+            %ul
+              %li= link_to t('about.terms'), terms_path
+              %li= link_to t('about.privacy_policy'), terms_path
+          .column-1
+            %h4= t 'footer.developers'
+            %ul
+              %li= link_to t('about.documentation'), 'https://docs.joinmastodon.org/'
+              %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')
+          .column-3
+            %h4= site_hostname
+            %ul
+              %li= link_to t('about.about_this'), about_more_path
+              %li= "v#{Mastodon::Version.to_s}"
+          .column-4
+            %h4= t 'footer.more'
+            %ul
+              %li= link_to t('about.source_code'), Mastodon::Version.source_url
+              %li= link_to t('about.apps'), 'https://joinmastodon.org/apps'
 
 = render template: 'layouts/application'
diff --git a/app/views/notification_mailer/digest.html.haml b/app/views/notification_mailer/digest.html.haml
index 10e44f8dde98e0d4a42a150d9e0a283773144936..a94ace228d84853c16f6c0dfac05cf54edb9414d 100644
--- a/app/views/notification_mailer/digest.html.haml
+++ b/app/views/notification_mailer/digest.html.haml
@@ -14,7 +14,7 @@
                           %tr
                             %td.column-cell.text-center.padded
                               %h1= t 'notification_mailer.digest.title'
-                              %p.lead= t('notification_mailer.digest.body', since: l(@since.to_date, format: :short), instance: site_hostname)
+                              %p.lead= t('notification_mailer.digest.body', since: l((@me.user_current_sign_in_at || @since).to_date, format: :short), instance: site_hostname)
                               %table.button{ align: 'center', cellspacing: 0, cellpadding: 0 }
                                 %tbody
                                   %tr
diff --git a/app/views/notification_mailer/digest.text.erb b/app/views/notification_mailer/digest.text.erb
index e0d1f9b8b9d0bd9563130e30731597bfe52a82db..b2c85a9e3dcf3ee960834d9c8e716939ad3da697 100644
--- a/app/views/notification_mailer/digest.text.erb
+++ b/app/views/notification_mailer/digest.text.erb
@@ -1,6 +1,6 @@
 <%= raw t('application_mailer.salutation', name: display_name(@me)) %>
 
-<%= raw t('notification_mailer.digest.body', since: l(@since), instance: root_url) %>
+<%= raw t('notification_mailer.digest.body', since: l(@me.user_current_sign_in_at || @since), instance: root_url) %>
 <% @notifications.each do |notification| %>
 
 * <%= raw t('notification_mailer.digest.mention', name: notification.from_account.acct) %>
diff --git a/app/views/remote_follow/new.html.haml b/app/views/remote_follow/new.html.haml
index 9b22fda5f38c134a71c29707cfa7f55f77acf786..5cf6977ba17014fb4d3d156e41f1d1e129fcd66e 100644
--- a/app/views/remote_follow/new.html.haml
+++ b/app/views/remote_follow/new.html.haml
@@ -6,7 +6,7 @@
   .follow-prompt
     %h2= t('remote_follow.prompt')
 
-    = render partial: 'authorize_follows/card', locals: { account: @account }
+    = render partial: 'application/card', locals: { account: @account }
 
   = simple_form_for @remote_follow, as: :remote_follow, url: account_remote_follow_path(@account) do |f|
     = render 'shared/error_messages', object: @remote_follow
@@ -16,4 +16,6 @@
     .actions
       = f.button :button, t('remote_follow.proceed'), type: :submit
 
-    %p.hint.subtle-hint= t('remote_follow.no_account_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')
+    %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')
diff --git a/app/views/remote_interaction/new.html.haml b/app/views/remote_interaction/new.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..a0b10681483d97e76221390acf558de7a83a8110
--- /dev/null
+++ b/app/views/remote_interaction/new.html.haml
@@ -0,0 +1,21 @@
+.form-container
+  .follow-prompt
+    %h2= t("remote_interaction.#{@interaction_type}.prompt")
+
+    .public-layout
+      .activity-stream.activity-stream--highlighted
+        = render 'stream_entries/status', status: @status
+
+  = simple_form_for @remote_follow, as: :remote_follow, url: remote_interaction_path(@status) do |f|
+    = render 'shared/error_messages', object: @remote_follow
+
+    = hidden_field_tag :type, @interaction_type
+
+    = f.input :acct, placeholder: t('remote_follow.acct'), input_html: { autocapitalize: 'none', autocorrect: 'off' }
+
+    .actions
+      = f.button :button, t("remote_interaction.#{@interaction_type}.proceed"), type: :submit
+
+    %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')
diff --git a/app/views/remote_unfollows/success.html.haml b/app/views/remote_unfollows/success.html.haml
index aa3c838a09636f5d3ba845ec6328908cb286f4b7..b007eedc7e43c6f5de7295e8f3f904b08a5326ac 100644
--- a/app/views/remote_unfollows/success.html.haml
+++ b/app/views/remote_unfollows/success.html.haml
@@ -5,6 +5,6 @@
   .follow-prompt
     %h2= t('remote_unfollow.unfollowed')
 
-    = render 'card', account: @account
+    = render 'application/card', account: @account
 
   = render 'post_follow_actions'
diff --git a/app/views/settings/applications/_fields.html.haml b/app/views/settings/applications/_fields.html.haml
index db90df3491996f725488904979e5345c49f3197f..6a2863b200b00ce3d2e6a1cd12b7e31120a23fb0 100644
--- a/app/views/settings/applications/_fields.html.haml
+++ b/app/views/settings/applications/_fields.html.haml
@@ -1,6 +1,8 @@
 .fields-group
-  = f.input :name, placeholder: t('activerecord.attributes.doorkeeper/application.name')
-  = f.input :website, placeholder: t('activerecord.attributes.doorkeeper/application.website')
+  = f.input :name, wrapper: :with_label, label: t('activerecord.attributes.doorkeeper/application.name')
+
+.fields-group
+  = f.input :website, wrapper: :with_label, label: t('activerecord.attributes.doorkeeper/application.website')
 
 .fields-group
   = f.input :redirect_uri, wrapper: :with_block_label, label: t('activerecord.attributes.doorkeeper/application.redirect_uri'), hint: t('doorkeeper.applications.help.redirect_uri')
diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml
index 30cd26914076070c82742354b4caaf2799947b37..b13cea976a1de6e1a4b20a6418259f033dd0053c 100644
--- a/app/views/settings/exports/show.html.haml
+++ b/app/views/settings/exports/show.html.haml
@@ -8,18 +8,34 @@
         %th= t('exports.storage')
         %td= number_to_human_size @export.total_storage
         %td
+      %tr
+        %th= t('accounts.posts', count: @export.total_statuses)
+        %td= number_with_delimiter @export.total_statuses
+        %td
       %tr
         %th= t('exports.follows')
-        %td= number_to_human @export.total_follows
+        %td= number_with_delimiter @export.total_follows
         %td= table_link_to 'download', t('exports.csv'), settings_exports_follows_path(format: :csv)
+      %tr
+        %th= t('exports.lists')
+        %td= number_with_delimiter @export.total_lists
+        %td= table_link_to 'download', t('exports.csv'), settings_exports_lists_path(format: :csv)
+      %tr
+        %th= t('accounts.followers', count: @export.total_followers)
+        %td= number_with_delimiter @export.total_followers
+        %td
       %tr
         %th= t('exports.blocks')
-        %td= number_to_human @export.total_blocks
+        %td= number_with_delimiter @export.total_blocks
         %td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv)
       %tr
         %th= t('exports.mutes')
-        %td= number_to_human @export.total_mutes
+        %td= number_with_delimiter @export.total_mutes
         %td= table_link_to 'download', t('exports.csv'), settings_exports_mutes_path(format: :csv)
+      %tr
+        %th= t('exports.domain_blocks')
+        %td= number_with_delimiter @export.total_domain_blocks
+        %td= table_link_to 'download', t('exports.csv'), settings_exports_domain_blocks_path(format: :csv)
 
 %p.muted-hint= t('exports.archive_takeout.hint_html')
 
diff --git a/app/views/settings/imports/show.html.haml b/app/views/settings/imports/show.html.haml
index 991dd4e941d1f659b4fc1a20ab5cb56631cc9304..4512fc714dc7e929470a26a65052a0f04086bd67 100644
--- a/app/views/settings/imports/show.html.haml
+++ b/app/views/settings/imports/show.html.haml
@@ -1,11 +1,12 @@
 - content_for :page_title do
   = t('settings.import')
 
-%p.hint= t('imports.preface')
-
 = simple_form_for @import, url: settings_import_path do |f|
-  = f.input :type, collection: Import.types.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| I18n.t("imports.types.#{type}") }, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
-  = f.input :data, wrapper: :with_label, hint: t('simple_form.hints.imports.data')
+  .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')
 
   .actions
     = f.button :button, t('imports.upload'), type: :submit
diff --git a/app/views/settings/migrations/show.html.haml b/app/views/settings/migrations/show.html.haml
index b7c34761f30a47af75f0e0c35e2ff7fd962cf386..c69061d50bcd023a2b0c82e7ad6e5f253b1db4c7 100644
--- a/app/views/settings/migrations/show.html.haml
+++ b/app/views/settings/migrations/show.html.haml
@@ -6,7 +6,7 @@
     %p.hint= t('migrations.currently_redirecting')
 
     .fields-group
-      = render partial: 'authorize_follows/card', locals: { account: @migration.account }
+      = render partial: 'application/card', locals: { account: @migration.account }
 
   = render 'shared/error_messages', object: @migration
 
diff --git a/app/views/settings/notifications/show.html.haml b/app/views/settings/notifications/show.html.haml
index b718b62df5694f249df6618c116bf4dc5dbfd05b..8aaac043b711d013dfe2231c94fbda6718234542 100644
--- a/app/views/settings/notifications/show.html.haml
+++ b/app/views/settings/notifications/show.html.haml
@@ -12,6 +12,9 @@
       = ff.input :favourite, as: :boolean, wrapper: :with_label
       = ff.input :mention, as: :boolean, wrapper: :with_label
 
+      - if current_user.staff?
+        = ff.input :report, as: :boolean, wrapper: :with_label
+
   .fields-group
     = f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff|
       = ff.input :digest, as: :boolean, wrapper: :with_label
diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml
index 43430069f6e224f4b41e5eee8d361e3be77ea5f6..a2c61c9a6810c1a1c1a59225fb9957ca7d1c51b9 100644
--- a/app/views/settings/preferences/show.html.haml
+++ b/app/views/settings/preferences/show.html.haml
@@ -1,29 +1,32 @@
 - 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
 
-  .actions.actions--top
-    = f.button :button, t('generic.save_changes'), type: :submit
-
-  %h4= t 'preferences.languages'
+  .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 :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale
-
-    = 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
-
     = 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'
 
-  %h4= t 'preferences.publishing'
+  %hr#settings_publishing/
 
   .fields-group
-    = f.input :setting_default_privacy, collection: Status.visibilities.keys - ['direct'], wrapper: :with_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_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
 
-  %h4= t 'preferences.other'
+  %hr#settings_other/
 
   .fields-group
     = f.input :setting_noindex, as: :boolean, wrapper: :with_label
@@ -31,19 +34,25 @@
   .fields-group
     = f.input :setting_hide_network, as: :boolean, wrapper: :with_label
 
-  %h4= t 'preferences.web'
+  %hr#settings_web/
 
-  .fields-group
-    - if Themes.instance.names.size > 1
-      = f.input :setting_theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false
+  .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_display_sensitive_media, 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
 
diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml
index 658f29f579fd0fe87ac58168226e497465a993da..932638dbe2faac6c07b81ebd1fd624501fe89a8a 100644
--- a/app/views/settings/profiles/show.html.haml
+++ b/app/views/settings/profiles/show.html.haml
@@ -4,17 +4,21 @@
 = simple_form_for @account, url: settings_profile_path, html: { method: :put } do |f|
   = render 'shared/error_messages', object: @account
 
-  .fields-group
-    = f.input :display_name, placeholder: t('simple_form.labels.defaults.display_name'), hint: t('simple_form.hints.defaults.display_name', count: 30 - @account.display_name.size).html_safe
-    = f.input :note, placeholder: t('simple_form.labels.defaults.note'), hint: t('simple_form.hints.defaults.note', count: 65535 - @account.note.size).html_safe
+  .fields-row
+    .fields-row__column.fields-group.fields-row__column-6
+      = f.input :display_name, wrapper: :with_label, input_html: { maxlength: 30 }, hint: false
+      = f.input :note, wrapper: :with_label, input_html: { maxlength: 65535 }, hint: false
 
-  .card.compact{ style: "background-image: url(#{@account.header.url(:original)})", data: { original_src: @account.header.url(:original) } }
-    .avatar= image_tag @account.avatar.url(:original), data: { original_src: @account.avatar.url(:original) }
+  .fields-row
+    .fields-row__column.fields-row__column-6
+      = render 'application/card', account: @account
 
-  .fields-group
-    = f.input :avatar, wrapper: :with_label, input_html: { accept: AccountAvatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar')
+    .fields-row__column.fields-group.fields-row__column-6
+      = f.input :header, wrapper: :with_label, input_html: { accept: AccountHeader::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(AccountHeader::LIMIT))
+
+      = f.input :avatar, wrapper: :with_label, input_html: { accept: AccountAvatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(AccountAvatar::LIMIT))
 
-    = f.input :header, wrapper: :with_label, input_html: { accept: AccountHeader::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header')
+  %hr.spacer/
 
   .fields-group
     = f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked')
@@ -22,15 +26,31 @@
   .fields-group
     = f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot')
 
-  .fields-group
-    .input.with_block_label
-      %label= t('simple_form.labels.defaults.fields')
-      %span.hint= t('simple_form.hints.defaults.fields')
+  - 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)
+
+  %hr.spacer/
 
-      = f.simple_fields_for :fields do |fields_f|
-        .row
-          = fields_f.input :name, placeholder: t('simple_form.labels.account.fields.name')
-          = fields_f.input :value, placeholder: t('simple_form.labels.account.fields.value')
+  .fields-row
+    .fields-row__column.fields-group.fields-row__column-6
+      .input.with_block_label
+        %label= t('simple_form.labels.defaults.fields')
+        %span.hint= t('simple_form.hints.defaults.fields')
+
+        = f.simple_fields_for :fields do |fields_f|
+          .row
+            = fields_f.input :name, placeholder: t('simple_form.labels.account.fields.name'), input_html: { maxlength: 255 }
+            = fields_f.input :value, placeholder: t('simple_form.labels.account.fields.value'), input_html: { maxlength: 255 }
+
+    .fields-row__column.fields-group.fields-row__column-6
+      %h6= t('verification.verification')
+      %p.hint= t('verification.explanation_html')
+
+      .input-copy
+        .input-copy__wrapper
+          %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: link_to('Mastodon', ActivityPub::TagManager.instance.url_for(@account), rel: 'me').to_str }
+        %button{ type: :button }= t('generic.copy')
 
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit
@@ -39,3 +59,9 @@
 
 %h6= t('auth.migrate_account')
 %p.muted-hint= t('auth.migrate_account_html', path: settings_migration_path)
+
+- if open_deletion?
+  %hr.spacer/
+
+  %h6= t('auth.delete_account')
+  %p.muted-hint= t('auth.delete_account_html', path: settings_delete_path)
diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml
index fd4a3e768344b42377766a65fb5ab3599c6e44fa..e641552991c0bb6ed494214c8482404f1b830f72 100644
--- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml
+++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml
@@ -11,7 +11,8 @@
       %p.hint= t('two_factor_authentication.manual_instructions')
       %samp.qr-alternative__code= current_user.otp_secret.scan(/.{4}/).join(' ')
 
-  = f.input :code, hint: t('two_factor_authentication.code_hint'), placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }
+  .fields-group
+    = f.input :code, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true
 
   .actions
     = f.button :button, t('two_factor_authentication.enable'), type: :submit
diff --git a/app/views/settings/two_factor_authentications/show.html.haml b/app/views/settings/two_factor_authentications/show.html.haml
index 67a64a0468f587c708899d9f6916ff991a55d73b..259bcd1ef33aeb5256d8d50ff810b5d2c6aa751b 100644
--- a/app/views/settings/two_factor_authentications/show.html.haml
+++ b/app/views/settings/two_factor_authentications/show.html.haml
@@ -10,7 +10,7 @@
   %hr/
 
   = simple_form_for @confirmation, url: settings_two_factor_authentication_path, method: :delete do |f|
-    = f.input :code, hint: t('two_factor_authentication.code_hint'), placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }
+    = f.input :code, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true
 
     .actions
       = f.button :button, t('two_factor_authentication.disable'), type: :submit
diff --git a/app/views/shared/_error_messages.html.haml b/app/views/shared/_error_messages.html.haml
index b73890216f5091895dfdb78aa190e0d381aa2d58..28becd6c4482da59d232e33a93894b9e4279ed91 100644
--- a/app/views/shared/_error_messages.html.haml
+++ b/app/views/shared/_error_messages.html.haml
@@ -1,3 +1,3 @@
 - if object.errors.any?
-  .flash-message#error_explanation
+  .flash-message.alert#error_explanation
     %strong= t('generic.validation_errors', count: object.errors.count)
diff --git a/app/views/shared/_landing_strip.html.haml b/app/views/shared/_landing_strip.html.haml
deleted file mode 100644
index 9a4144723f91a5f46a5bd8274d376710ba1a4668..0000000000000000000000000000000000000000
--- a/app/views/shared/_landing_strip.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-.landing-strip
-  = image_tag asset_pack_path('logo.svg'), class: 'logo'
-
-  %div
-    = t('landing_strip_html', name: content_tag(:span, display_name(account, custom_emojify: true), class: :emojify), link_to_root_path: link_to(content_tag(:strong, site_hostname), root_path))
-    = t('landing_strip_signup_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')
diff --git a/app/views/shared/_og.html.haml b/app/views/shared/_og.html.haml
index a6d805bea22ab334b5570868ad8c8d681d5a9859..802d8c41d4596c3e04b1944456c3c6e9930c8357 100644
--- a/app/views/shared/_og.html.haml
+++ b/app/views/shared/_og.html.haml
@@ -1,9 +1,13 @@
 - thumbnail = @instance_presenter.thumbnail
+- description = strip_tags(@instance_presenter.site_short_description.presence || @instance_presenter.site_description.presence || t('about.about_mastodon_html'))
+
+%meta{ name: 'description', content: description }/
+
 = opengraph 'og:site_name', t('about.hosted_on', domain: site_hostname)
 = opengraph 'og:url', url_for(only_path: false)
 = opengraph 'og:type', 'website'
 = opengraph 'og:title', @instance_presenter.site_title
-= opengraph 'og:description', strip_tags(@instance_presenter.site_description.presence || t('about.about_mastodon_html'))
+= opengraph 'og:description', description
 = opengraph 'og:image', full_asset_url(thumbnail&.file&.url || asset_pack_path('preview.jpg', protocol: :request))
 = opengraph 'og:image:width', thumbnail ? thumbnail.meta['width'] : '1200'
 = opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630'
diff --git a/app/views/stream_entries/_attachment_list.html.haml b/app/views/stream_entries/_attachment_list.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..d9706f47bd849a1db87c24e30dc431345d3beb7e
--- /dev/null
+++ b/app/views/stream_entries/_attachment_list.html.haml
@@ -0,0 +1,8 @@
+.attachment-list
+  .attachment-list__icon
+    = fa_icon 'link'
+  %ul.attachment-list__list
+    - attachments.each do |media|
+      %li
+        - url = media.remote_url.presence || media.file.url
+        = link_to File.basename(url), url, title: media.description
diff --git a/app/views/stream_entries/_content_spoiler.html.haml b/app/views/stream_entries/_content_spoiler.html.haml
deleted file mode 100644
index 798dfce670da4d8c05dcc65247d0d75dbd7c9c43..0000000000000000000000000000000000000000
--- a/app/views/stream_entries/_content_spoiler.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-.media-spoiler-wrapper{ class: sensitive == false && 'media-spoiler-wrapper__visible' }
-  .spoiler-button
-    .icon-button.overlayed
-      %i.fa.fa-fw.fa-eye
-  .media-spoiler
-    %span= t('stream_entries.sensitive_content')
-    %span= t('stream_entries.click_to_show')
diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml
index db09dd6f34c20376e802beb2ec572ce9e072b684..27170d2c6388eca0627affc46d27ac390b4fa842 100644
--- a/app/views/stream_entries/_detailed_status.html.haml
+++ b/app/views/stream_entries/_detailed_status.html.haml
@@ -1,35 +1,41 @@
-.detailed-status.light
-  = link_to TagManager.instance.url_for(status.account), class: 'detailed-status__display-name p-author h-card', target: stream_link_target, rel: 'noopener' do
-    %div
-      .avatar
-        = image_tag status.account.avatar.url(:original), width: 48, height: 48, alt: '', class: 'u-photo'
-    %span.display-name
-      %strong.p-name.emojify= display_name(status.account, custom_emojify: true)
-      %span= acct(status.account)
+.detailed-status.detailed-status--flex
+  .p-author.h-card
+    = link_to TagManager.instance.url_for(status.account), class: 'detailed-status__display-name u-url', target: stream_link_target, rel: 'noopener' do
+      .detailed-status__display-avatar
+        - if current_account&.user&.setting_auto_play_gif || autoplay
+          = image_tag status.account.avatar_original_url, width: 48, height: 48, alt: '', class: 'account__avatar u-photo'
+        - else
+          = image_tag status.account.avatar_static_url, width: 48, height: 48, alt: '', class: 'account__avatar u-photo'
+      %span.display-name
+        %bdi
+          %strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true, autoplay: autoplay)
+        %span.display-name__account
+          = acct(status.account)
+          = fa_icon('lock') if status.account.locked?
 
-  - if !user_signed_in? || embedded_view?
-    = link_to account_remote_follow_path(status.account), class: 'button button-secondary logo-button', target: '_new' do
-      = render file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')
-      = t('accounts.follow')
+  = account_action_button(status.account)
 
   .status__content.emojify<
     - if status.spoiler_text?
-      %p{ style: 'margin-bottom: 0' }<
-        %span.p-summary> #{Formatter.instance.format_spoiler(status)}&nbsp;
+      %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: #{status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true)
+    .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.media_attachments.empty?
     - if status.media_attachments.first.video?
       - video = status.media_attachments.first
-      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true
+      = 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
+        = render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
     - else
-      = react_component :media_gallery, height: 380, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
-  - elsif status.preview_cards.first
-    = react_component :card, 'maxDescription': 65535, card: ActiveModelSerializers::SerializableResource.new(status.preview_cards.first, serializer: REST::PreviewCardSerializer).as_json
+      = 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
+        = render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
+  - elsif status.preview_card
+    = react_component :card, 'maxDescription': 65535, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json
 
   .detailed-status__meta
     %data.dt-published{ value: status.created_at.to_time.iso8601 }
+
     = 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)
     ·
@@ -39,21 +45,31 @@
       - else
         = link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener'
       ·
+    = link_to remote_interaction_path(status, type: :reply), class: 'modal-button detailed-status__link' do
+      - if status.in_reply_to_id.nil?
+        = fa_icon('reply')
+      - else
+        = fa_icon('reply-all')
+      %span.detailed-status__reblogs>= number_to_human status.replies_count, strip_insignificant_zeros: true
+      = " "
+    ·
     - if status.direct_visibility?
-      %span<
+      %span.detailed-status__link<
         = fa_icon('envelope')
-    - elsif status.private_visibility?
-      %span<
+    - elsif status.private_visibility? || status.limited_visibility?
+      %span.detailed-status__link<
         = fa_icon('lock')
     - else
-      %span<
+      = link_to remote_interaction_path(status, type: :reblog), class: 'modal-button detailed-status__link' do
         = fa_icon('retweet')
-        %span= status.reblogs_count
+        %span.detailed-status__reblogs>= number_to_human status.reblogs_count, strip_insignificant_zeros: true
+        = " "
     ·
-    %span<
+    = link_to remote_interaction_path(status, type: :favourite), class: 'modal-button detailed-status__link' do
       = fa_icon('star')
-      %span= status.favourites_count
+      %span.detailed-status__favorites>= number_to_human status.favourites_count, strip_insignificant_zeros: true
+      = " "
 
     - if user_signed_in?
       ·
-      = link_to t('statuses.open_in_web'), web_url("statuses/#{status.id}"), class: 'open-in-web-link', target: '_blank'
+      = link_to t('statuses.open_in_web'), web_url("statuses/#{status.id}"), class: 'detailed-status__application', target: '_blank'
diff --git a/app/views/stream_entries/_media.html.haml b/app/views/stream_entries/_media.html.haml
deleted file mode 100644
index 779f02c8d9166be02264f565daab4f8d7c17f1e1..0000000000000000000000000000000000000000
--- a/app/views/stream_entries/_media.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-.media-item
-  = link_to media.remote_url.blank? ? media.file.url(:original) : media.remote_url, style: media.image? ? "background-image: url(#{media.file.url(:original)})" : '', target: '_blank', rel: 'noopener', class: "u-#{media.video? || media.gifv? ? 'video' : 'photo'}" do
-    - unless media.image?
-      %video{ src: media.file.url(:original), autoplay: true, loop: true }/
diff --git a/app/views/stream_entries/_more.html.haml b/app/views/stream_entries/_more.html.haml
deleted file mode 100644
index 9b1dfe4a71e913fc886506b23b8ad0643cc54b14..0000000000000000000000000000000000000000
--- a/app/views/stream_entries/_more.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-= link_to url, class: 'more light'  do
-  = t('statuses.show_more')
diff --git a/app/views/stream_entries/_og_description.html.haml b/app/views/stream_entries/_og_description.html.haml
index 3d122b94ef4efde8dfa8e68f5b387d6c6db7b252..a7b18424d28f178b64ef63a7584ebbaca0e55b6e 100644
--- a/app/views/stream_entries/_og_description.html.haml
+++ b/app/views/stream_entries/_og_description.html.haml
@@ -1 +1,4 @@
-= opengraph 'og:description', status_description(activity)
+- description = status_description(activity)
+
+%meta{ name: 'description', content: description }/
+= opengraph 'og:description', description
diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml
index 0f27585a16aa689c5ad0afb071cd7769eca0c08b..b0b6e80c89bf7176ce307dedba60cda16f2a661d 100644
--- a/app/views/stream_entries/_simple_status.html.haml
+++ b/app/views/stream_entries/_simple_status.html.haml
@@ -1,28 +1,56 @@
-.status.light
-  .status__header
-    .status__meta
-      = link_to TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener' do
-        %time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
-      %data.dt-published{ value: status.created_at.to_time.iso8601 }
-
-    = link_to TagManager.instance.url_for(status.account), class: 'status__display-name p-author h-card', target: stream_link_target, rel: 'noopener' do
-      .status__avatar
-        %div
-          = image_tag status.account.avatar(:original), width: 48, height: 48, alt: '', class: 'u-photo'
-      %span.display-name
-        %strong.p-name.emojify= display_name(status.account, custom_emojify: true)
-        %span= acct(status.account)
+.status
+  .status__info
+    = link_to TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener' do
+      %time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
+    %data.dt-published{ value: status.created_at.to_time.iso8601 }
 
+    .p-author.h-card
+      = link_to TagManager.instance.url_for(status.account), class: 'status__display-name u-url', target: stream_link_target, rel: 'noopener' do
+        .status__avatar
+          %div
+            - if current_account&.user&.setting_auto_play_gif || autoplay
+              = image_tag status.account.avatar_original_url, width: 48, height: 48, alt: '', class: 'u-photo account__avatar'
+            - else
+              = image_tag status.account.avatar_static_url, width: 48, height: 48, alt: '', class: 'u-photo account__avatar'
+        %span.display-name
+          %bdi
+            %strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true, autoplay: autoplay)
+          &nbsp;
+          %span.display-name__account
+            = acct(status.account)
+            = fa_icon('lock') if status.account.locked?
   .status__content.emojify<
     - if status.spoiler_text?
-      %p{ style: 'margin-bottom: 0' }<
-        %span.p-summary> #{Formatter.instance.format_spoiler(status)}&nbsp;
+      %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: #{status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true)
+    .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)
 
-  - unless status.media_attachments.empty?
+  - if !status.media_attachments.empty?
     - if status.media_attachments.first.video?
       - video = status.media_attachments.first
-      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
+      = 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
+        = render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
     - else
-      = react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
+      = 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
+        = render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
+  - elsif status.preview_card
+    = react_component :card, 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json
+
+  .status__action-bar
+    .status__action-bar__counter
+      = link_to remote_interaction_path(status, type: :reply), class: 'status__action-bar-button icon-button modal-button', style: 'font-size: 18px; width: 23.1429px; height: 23.1429px; line-height: 23.15px;' do
+        - if status.in_reply_to_id.nil?
+          = fa_icon 'reply fw'
+        - else
+          = fa_icon 'reply-all fw'
+      .status__action-bar__counter__label= obscured_counter status.replies_count
+    = link_to remote_interaction_path(status, type: :reblog), class: 'status__action-bar-button icon-button modal-button', style: 'font-size: 18px; width: 23.1429px; height: 23.1429px; line-height: 23.15px;' do
+      - if status.public_visibility? || status.unlisted_visibility?
+        = fa_icon 'retweet fw'
+      - elsif status.private_visibility?
+        = fa_icon 'lock fw'
+      - else
+        = fa_icon 'envelope fw'
+    = link_to remote_interaction_path(status, type: :favourite), class: 'status__action-bar-button icon-button modal-button', style: 'font-size: 18px; width: 23.1429px; height: 23.1429px; line-height: 23.15px;' do
+      = fa_icon 'star fw'
diff --git a/app/views/stream_entries/_status.html.haml b/app/views/stream_entries/_status.html.haml
index b87ca217719f4182638aa3311be85981703276fa..83887cd87437f7a73548a5e69062c5cd3038f5da 100644
--- a/app/views/stream_entries/_status.html.haml
+++ b/app/views/stream_entries/_status.html.haml
@@ -5,6 +5,7 @@
   is_successor    ||= false
   direct_reply_id ||= false
   parent_id       ||= false
+  autoplay        ||= current_account&.user&.setting_auto_play_gif
   is_direct_parent  = direct_reply_id == status.id
   is_direct_child   = parent_id == status.in_reply_to_id
   centered        ||= include_threads && !is_predecessor && !is_successor
@@ -16,39 +17,46 @@
 - if status.reply? && include_threads
   - if @next_ancestor
     .entry{ class: entry_classes }
-      = render 'stream_entries/more', url: TagManager.instance.url_for(@next_ancestor)
+      = link_to_more TagManager.instance.url_for(@next_ancestor)
 
-  = render partial: 'stream_entries/status', collection: @ancestors, as: :status, locals: { is_predecessor: true, direct_reply_id: status.in_reply_to_id }
+  = render partial: 'stream_entries/status', collection: @ancestors, as: :status, locals: { is_predecessor: true, direct_reply_id: status.in_reply_to_id }, autoplay: autoplay
 
 .entry{ class: entry_classes }
 
   - if status.reblog?
-    .pre-header
-      .pre-header__icon
-        = fa_icon('retweet fw')
+    .status__prepend
+      .status__prepend-icon-wrapper
+        %i.status__prepend-icon.fa.fa-fw.fa-retweet
       %span
         = link_to TagManager.instance.url_for(status.account), class: 'status__display-name muted' do
-          %strong.emojify= display_name(status.account, custom_emojify: true)
+          %bdi
+            %strong.emojify= display_name(status.account, custom_emojify: true)
         = t('stream_entries.reblogged')
   - elsif pinned
-    .pre-header
-      .pre-header__icon
-        = fa_icon('thumb-tack fw')
+    .status__prepend
+      .status__prepend-icon-wrapper
+        %i.status__prepend-icon.fa.fa-fw.fa-thumb-tack
       %span
         = t('stream_entries.pinned')
 
-  = render (centered ? 'stream_entries/detailed_status' : 'stream_entries/simple_status'), status: status.proper
+  = render (centered ? 'stream_entries/detailed_status' : 'stream_entries/simple_status'), status: status.proper, autoplay: autoplay
 
 - if include_threads
   - if @since_descendant_thread_id
     .entry{ class: entry_classes }
-      = render 'stream_entries/more', url: short_account_status_url(status.account.username, status, max_descendant_thread_id: @since_descendant_thread_id + 1)
+      = link_to_more short_account_status_url(status.account.username, status, max_descendant_thread_id: @since_descendant_thread_id + 1)
   - @descendant_threads.each do |thread|
-    = render partial: 'stream_entries/status', collection: thread[:statuses], as: :status, locals: { is_successor: true, parent_id: status.id }
+    = render partial: 'stream_entries/status', collection: thread[:statuses], as: :status, locals: { is_successor: true, parent_id: status.id }, autoplay: autoplay
 
     - if thread[:next_status]
       .entry{ class: entry_classes }
-        = render 'stream_entries/more', url: TagManager.instance.url_for(thread[:next_status])
+        = link_to_more TagManager.instance.url_for(thread[:next_status])
   - if @next_descendant_thread
     .entry{ class: entry_classes }
-      = render 'stream_entries/more', url: short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1)
+      = link_to_more short_account_status_url(status.account.username, status, since_descendant_thread_id: @max_descendant_thread_id - 1)
+
+- if include_threads && !embedded_view? && !user_signed_in?
+  .entry{ class: entry_classes }
+    = link_to new_user_session_path, class: 'load-more load-gap' do
+      = fa_icon 'comments'
+      = t('statuses.sign_in_to_participate')
diff --git a/app/views/stream_entries/embed.html.haml b/app/views/stream_entries/embed.html.haml
index b703c15d2f022665078520060c7babdea9e01801..4871c101e1cbf38e2f6fc574d8850fdd3fab787e 100644
--- a/app/views/stream_entries/embed.html.haml
+++ b/app/views/stream_entries/embed.html.haml
@@ -1,3 +1,3 @@
 - cache @stream_entry.activity do
-  .activity-stream.activity-stream-headless
-    = render "stream_entries/#{@type}", @type.to_sym => @stream_entry.activity, centered: true
+  .activity-stream.activity-stream--headless
+    = render "stream_entries/#{@type}", @type.to_sym => @stream_entry.activity, centered: true, autoplay: @autoplay
diff --git a/app/views/stream_entries/show.html.haml b/app/views/stream_entries/show.html.haml
index dfb83e747b3ec2c82ad2e3fc6b9dabe3b7ce5b03..0e81c4f6853f6756772246d043d3855174bad39c 100644
--- a/app/views/stream_entries/show.html.haml
+++ b/app/views/stream_entries/show.html.haml
@@ -12,13 +12,14 @@
   = 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, @stream_entry)
+  = opengraph 'og:url', short_account_status_url(@account, @stream_entry.activity)
 
   = render 'stream_entries/og_description', activity: @stream_entry.activity
   = render 'stream_entries/og_image', activity: @stream_entry.activity, account: @account
 
-- if show_landing_strip?
-  = render partial: 'shared/landing_strip', locals: { account: @stream_entry.account }
-
-.activity-stream.activity-stream-headless.h-entry
-  = render partial: "stream_entries/#{@type}", locals: { @type.to_sym => @stream_entry.activity, include_threads: true }
+.grid
+  .column-0
+    .activity-stream.h-entry
+      = render partial: "stream_entries/#{@type}", locals: { @type.to_sym => @stream_entry.activity, include_threads: true }
+  .column-1
+    = render 'application/sidebar'
diff --git a/app/views/tags/_features.html.haml b/app/views/tags/_features.html.haml
deleted file mode 100644
index 8fbc6b7607334ae839704962f6555263c7ccf3ff..0000000000000000000000000000000000000000
--- a/app/views/tags/_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/tags/show.html.haml b/app/views/tags/show.html.haml
index f6e452f188e9d551b9f378617c3e9819412d1b8f..18de48eea2cc9201efcb992cc6fe1a3a4acb93ce 100644
--- a/app/views/tags/show.html.haml
+++ b/app/views/tags/show.html.haml
@@ -8,33 +8,9 @@
   = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
   = render 'og'
 
-.landing-page.tag-page.alternative
-  .features
-    .container
-      .grid
-        .column-1
-          #mastodon-timeline{ data: { props: Oj.dump(default_props.merge(hashtag: @tag.name)) } }
-
-        .column-2
-          .about-mastodon
-            .about-hashtag.landing-page__information
-              .brand
-                = link_to root_url do
-                  = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
-
-              %p= t 'about.about_hashtag_html', hashtag: @tag.name
-
-              .cta
-                - if user_signed_in?
-                  = link_to t('settings.back'), root_path, class: 'button button-secondary'
-                - else
-                  = link_to t('auth.login'), new_user_session_path, class: 'button button-secondary'
-                = link_to t('about.learn_more'), about_path, class: 'button button-alternative'
-
-            .landing-page__features.landing-page__information
-              %h3= t 'about.what_is_mastodon'
-              %p= t 'about.about_mastodon_html'
-
-              = render 'features'
+.page-header
+  %h1= "##{@tag.name}"
+  %p= t('about.about_hashtag_html', hashtag: @tag.name)
 
+#mastodon-timeline{ data: { props: Oj.dump(default_props.merge(hashtag: @tag.name)) }}
 #modal-container
diff --git a/app/views/user_mailer/confirmation_instructions.html.haml b/app/views/user_mailer/confirmation_instructions.html.haml
index 1f088a16f4f6b2fc0cd8d327de6e0bd665f4fa80..f75f7529a8f2286c19862413fe387f1695ec3356 100644
--- a/app/views/user_mailer/confirmation_instructions.html.haml
+++ b/app/views/user_mailer/confirmation_instructions.html.haml
@@ -55,8 +55,12 @@
                             %tbody
                               %tr
                                 %td.button-primary
-                                  = link_to confirmation_url(@resource, confirmation_token: @token) do
-                                    %span= t 'devise.mailer.confirmation_instructions.action'
+                                  - if @resource.created_by_application
+                                    = link_to confirmation_url(@resource, confirmation_token: @token, redirect_to_app: 'true') do
+                                      %span= t 'devise.mailer.confirmation_instructions.action_with_app', app: @resource.created_by_application.name
+                                  - else
+                                    = link_to confirmation_url(@resource, confirmation_token: @token) do
+                                      %span= t 'devise.mailer.confirmation_instructions.action'
 
 %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 e01eecb27e263a6256bc4c7ef9e36c62132377b6..65b4626c669d07a0c3a738ae58d058ea0e8ce83a 100644
--- a/app/views/user_mailer/confirmation_instructions.text.erb
+++ b/app/views/user_mailer/confirmation_instructions.text.erb
@@ -4,7 +4,7 @@
 
 <%= t 'devise.mailer.confirmation_instructions.explanation', host: site_hostname %>
 
-=> <%= confirmation_url(@resource, confirmation_token: @token) %>
+=> <%= confirmation_url(@resource, confirmation_token: @token, redirect_to_app: @resource.created_by_application ? 'true' : nil) %>
 
 <%= strip_tags(t('devise.mailer.confirmation_instructions.extra_html', terms_path: about_more_url, policy_path: terms_url)) %>
 
diff --git a/app/views/user_mailer/warning.html.haml b/app/views/user_mailer/warning.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..c5e1f5a289832833a7722588dc886068358f6a37
--- /dev/null
+++ b/app/views/user_mailer/warning.html.haml
@@ -0,0 +1,63 @@
+%table.email-table{ cellspacing: 0, cellpadding: 0 }
+  %tbody
+    %tr
+      %td.email-body
+        .email-container
+          %table.content-section{ cellspacing: 0, cellpadding: 0 }
+            %tbody
+              %tr
+                %td.content-cell.hero
+                  .email-row
+                    .col-6
+                      %table.column{ cellspacing: 0, cellpadding: 0 }
+                        %tbody
+                          %tr
+                            %td.column-cell.text-center.padded
+                              %table.hero-icon.alert-icon{ align: 'center', cellspacing: 0, cellpadding: 0 }
+                                %tbody
+                                  %tr
+                                    %td
+                                      = image_tag full_pack_url('icon_warning.png'), alt: ''
+
+                              %h1= t "user_mailer.warning.title.#{@warning.action}"
+
+%table.email-table{ cellspacing: 0, cellpadding: 0 }
+  %tbody
+    %tr
+      %td.email-body
+        .email-container
+          %table.content-section{ cellspacing: 0, cellpadding: 0 }
+            %tbody
+              %tr
+                %td.content-cell.content-start
+                  .email-row
+                    .col-6
+                      %table.column{ cellspacing: 0, cellpadding: 0 }
+                        %tbody
+                          %tr
+                            %td.column-cell.text-center
+                              - unless @warning.none_action?
+                                %p= t "user_mailer.warning.explanation.#{@warning.action}"
+
+                              - unless @warning.text.blank?
+                                = Formatter.instance.linkify(@warning.text)
+
+%table.email-table{ cellspacing: 0, cellpadding: 0 }
+  %tbody
+    %tr
+      %td.email-body
+        .email-container
+          %table.content-section{ cellspacing: 0, cellpadding: 0 }
+            %tbody
+              %tr
+                %td.content-cell
+                  %table.column{ cellspacing: 0, cellpadding: 0 }
+                    %tbody
+                      %tr
+                        %td.column-cell.button-cell
+                          %table.button{ align: 'center', cellspacing: 0, cellpadding: 0 }
+                            %tbody
+                              %tr
+                                %td.button-primary
+                                  = link_to about_more_url do
+                                    %span= t 'user_mailer.warning.review_server_policies'
diff --git a/app/views/user_mailer/warning.text.erb b/app/views/user_mailer/warning.text.erb
new file mode 100644
index 0000000000000000000000000000000000000000..b4f2402cb3743e0d2f237f3e23e4bfcb1f3473d9
--- /dev/null
+++ b/app/views/user_mailer/warning.text.erb
@@ -0,0 +1,9 @@
+<%= t "user_mailer.warning.title.#{@warning.action}" %>
+
+===
+
+<% unless @warning.none_action? %>
+<%= t "user_mailer.warning.explanation.#{@warning.action}" %>
+
+<% end %>
+<%= @warning.text %>
diff --git a/app/views/user_mailer/welcome.html.haml b/app/views/user_mailer/welcome.html.haml
index d734da67db2d2cde0cccd507d9f3b5cf092022fc..4a5788bf6e507674e734701bf05232f4decc3b2a 100644
--- a/app/views/user_mailer/welcome.html.haml
+++ b/app/views/user_mailer/welcome.html.haml
@@ -136,8 +136,6 @@
                               %ul
                                 %li
                                   %span= t 'user_mailer.welcome.tip_mobile_webapp'
-                                %li
-                                  %span= t 'user_mailer.welcome.tip_bridge_html', bridge_url: 'https://bridge.joinmastodon.org'
                                 %li
                                   %span= t 'user_mailer.welcome.tip_following'
                                 %li
diff --git a/app/views/user_mailer/welcome.text.erb b/app/views/user_mailer/welcome.text.erb
index 5bd0cab2a5879912e72aba30523429cb22b67786..e310d7ca6f963a1e6e431b847defbe5fdb5d1c0a 100644
--- a/app/views/user_mailer/welcome.text.erb
+++ b/app/views/user_mailer/welcome.text.erb
@@ -2,7 +2,7 @@
 
 ===
 
-<%= t 'user_mailer.welcome.full_handle' %> (<%= "@#{@resource.account.username}@#{@instance}" %>)
+<%= t 'user_mailer.welcome.full_handle' %> (<%= "@#{@resource.account.local_username_and_domain}" %>)
 <%= t 'user_mailer.welcome.full_handle_hint', instance: @instance %>
 
 ---
@@ -24,7 +24,6 @@
 <%= t 'user_mailer.welcome.tips' %>
 
 * <%= t 'user_mailer.welcome.tip_mobile_webapp' %>
-* <%= strip_tags(t('user_mailer.welcome.tip_bridge_html')) %> (https://bridge.joinmastodon.org)
 * <%= t 'user_mailer.welcome.tip_following' %>
 * <%= t 'user_mailer.welcome.tip_local_timeline', instance: @instance %>
 * <%= t 'user_mailer.welcome.tip_federated_timeline' %>
diff --git a/app/views/well_known/webfinger/show.xml.ruby b/app/views/well_known/webfinger/show.xml.ruby
index 4352a24e910f4176835d5d3dfb53463cd31036ba..968c8c1380c0d70543e60ce8f9348e18a5f1735d 100644
--- a/app/views/well_known/webfinger/show.xml.ruby
+++ b/app/views/well_known/webfinger/show.xml.ruby
@@ -37,7 +37,7 @@ doc << Ox::Element.new('XRD').tap do |xrd|
 
   xrd << Ox::Element.new('Link').tap do |link|
     link['rel']      = 'http://ostatus.org/schema/1.0/subscribe'
-    link['template'] = "#{authorize_follow_url}?acct={uri}"
+    link['template'] = "#{authorize_interaction_url}?acct={uri}"
   end
 end
 
diff --git a/app/workers/activitypub/delivery_worker.rb b/app/workers/activitypub/delivery_worker.rb
index 323a9f85b91820fa39494cd2f4685ea83ffe95a0..f9c385ea3e20ab77f7a5ef4ebeaed47e4b497d23 100644
--- a/app/workers/activitypub/delivery_worker.rb
+++ b/app/workers/activitypub/delivery_worker.rb
@@ -10,7 +10,10 @@ class ActivityPub::DeliveryWorker
 
   HEADERS = { 'Content-Type' => 'application/activity+json' }.freeze
 
-  def perform(json, source_account_id, inbox_url)
+  def perform(json, source_account_id, inbox_url, options = {})
+    return if DeliveryFailureTracker.unavailable?(inbox_url)
+
+    @options        = options.with_indifferent_access
     @json           = json
     @source_account = Account.find(source_account_id)
     @inbox_url      = inbox_url
@@ -27,7 +30,7 @@ class ActivityPub::DeliveryWorker
 
   def build_request
     request = Request.new(:post, @inbox_url, body: @json)
-    request.on_behalf_of(@source_account, :uri)
+    request.on_behalf_of(@source_account, :uri, sign_with: @options[:sign_with])
     request.add_headers(HEADERS)
   end
 
diff --git a/app/workers/activitypub/distribution_worker.rb b/app/workers/activitypub/distribution_worker.rb
index 14bb933c0066684fa6a53d3e7a10d03fc1d7f7c9..d83f017000896eb9dc0f9320f65a1db544da839d 100644
--- a/app/workers/activitypub/distribution_worker.rb
+++ b/app/workers/activitypub/distribution_worker.rb
@@ -12,8 +12,10 @@ class ActivityPub::DistributionWorker
     return if skip_distribution?
 
     ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
-      [signed_payload, @account.id, inbox_url]
+      [payload, @account.id, inbox_url]
     end
+
+    relay! if relayable?
   rescue ActiveRecord::RecordNotFound
     true
   end
@@ -21,22 +23,43 @@ class ActivityPub::DistributionWorker
   private
 
   def skip_distribution?
-    @status.direct_visibility?
+    @status.direct_visibility? || @status.limited_visibility?
+  end
+
+  def relayable?
+    @status.public_visibility?
   end
 
   def inboxes
-    @inboxes ||= @account.followers.inboxes
+    # Deliver the status to all followers.
+    # If the status is a reply to another local status, also forward it to that
+    # status' authors' followers.
+    @inboxes ||= if @status.reply? && @status.thread.account.local? && @status.distributable?
+                   @account.followers.or(@status.thread.account.followers).inboxes
+                 else
+                   @account.followers.inboxes
+                 end
   end
 
   def signed_payload
-    @signed_payload ||= Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
+    Oj.dump(ActivityPub::LinkedDataSignature.new(unsigned_payload).sign!(@account))
   end
 
-  def payload
-    @payload ||= ActiveModelSerializers::SerializableResource.new(
+  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)
+  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/processing_worker.rb b/app/workers/activitypub/processing_worker.rb
index 0e2e0edddba98b56db5ab48e7056e5e147d672ab..a8a3ebf0f56987c433c8ccc67d7bfe45543318e9 100644
--- a/app/workers/activitypub/processing_worker.rb
+++ b/app/workers/activitypub/processing_worker.rb
@@ -5,7 +5,7 @@ class ActivityPub::ProcessingWorker
 
   sidekiq_options backtrace: true
 
-  def perform(account_id, body)
-    ActivityPub::ProcessCollectionService.new.call(body, Account.find(account_id), override_timestamps: 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)
   end
 end
diff --git a/app/workers/activitypub/reply_distribution_worker.rb b/app/workers/activitypub/reply_distribution_worker.rb
index fe99fc05f295691d412417fd555c056f1fcf5384..d8fea6c4e5cafacbca0fc15f10373ce44ab0edb7 100644
--- a/app/workers/activitypub/reply_distribution_worker.rb
+++ b/app/workers/activitypub/reply_distribution_worker.rb
@@ -1,5 +1,8 @@
 # frozen_string_literal: true
 
+# Obsolete but kept around to make sure existing jobs do not fail after upgrade.
+# Should be removed in a subsequent release.
+
 class ActivityPub::ReplyDistributionWorker
   include Sidekiq::Worker
 
@@ -9,10 +12,10 @@ class ActivityPub::ReplyDistributionWorker
     @status  = Status.find(status_id)
     @account = @status.thread&.account
 
-    return if @account.nil? || skip_distribution?
+    return unless @account.present? && @status.distributable?
 
     ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
-      [signed_payload, @status.account_id, inbox_url]
+      [payload, @status.account_id, inbox_url]
     end
   rescue ActiveRecord::RecordNotFound
     true
@@ -20,23 +23,23 @@ class ActivityPub::ReplyDistributionWorker
 
   private
 
-  def skip_distribution?
-    @status.private_visibility? || @status.direct_visibility?
-  end
-
   def inboxes
     @inboxes ||= @account.followers.inboxes
   end
 
   def signed_payload
-    @signed_payload ||= Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@status.account))
+    Oj.dump(ActivityPub::LinkedDataSignature.new(unsigned_payload).sign!(@status.account))
   end
 
-  def payload
-    @payload ||= ActiveModelSerializers::SerializableResource.new(
+  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)
+  end
 end
diff --git a/app/workers/activitypub/update_distribution_worker.rb b/app/workers/activitypub/update_distribution_worker.rb
index f3377dcec5a38e0389a4ac0eeecf7edbd2c8b176..b9e5ff064f2e532ec1eb8b2c79eb6867badfab1d 100644
--- a/app/workers/activitypub/update_distribution_worker.rb
+++ b/app/workers/activitypub/update_distribution_worker.rb
@@ -5,11 +5,16 @@ class ActivityPub::UpdateDistributionWorker
 
   sidekiq_options queue: 'push'
 
-  def perform(account_id)
+  def perform(account_id, options = {})
+    @options = options.with_indifferent_access
     @account = Account.find(account_id)
 
     ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
-      [payload, @account.id, inbox_url]
+      [signed_payload, @account.id, inbox_url]
+    end
+
+    ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
+      [signed_payload, @account.id, inbox_url]
     end
   rescue ActiveRecord::RecordNotFound
     true
@@ -21,11 +26,15 @@ class ActivityPub::UpdateDistributionWorker
     @inboxes ||= @account.followers.inboxes
   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
-    ).to_json
+    ).as_json
   end
 end
diff --git a/app/workers/admin/suspension_worker.rb b/app/workers/admin/suspension_worker.rb
index e41465ccca02223ec367ec8dd60868417a20933c..ae8b24d8c3e34823caf1cbfc0ab2b7c083d6cb5c 100644
--- a/app/workers/admin/suspension_worker.rb
+++ b/app/workers/admin/suspension_worker.rb
@@ -6,6 +6,6 @@ class Admin::SuspensionWorker
   sidekiq_options queue: 'pull'
 
   def perform(account_id, remove_user = false)
-    SuspendAccountService.new.call(Account.find(account_id), remove_user: remove_user)
+    SuspendAccountService.new.call(Account.find(account_id), including_user: remove_user)
   end
 end
diff --git a/app/workers/block_worker.rb b/app/workers/block_worker.rb
index 0820490d39f71328d15f862c12d2999f8e5b4741..25f5dd808fdb3590d5c0f2d3000fb5177a7568df 100644
--- a/app/workers/block_worker.rb
+++ b/app/workers/block_worker.rb
@@ -4,6 +4,9 @@ class BlockWorker
   include Sidekiq::Worker
 
   def perform(account_id, target_account_id)
-    AfterBlockService.new.call(Account.find(account_id), Account.find(target_account_id))
+    AfterBlockService.new.call(
+      Account.find(account_id),
+      Account.find(target_account_id)
+    )
   end
 end
diff --git a/app/workers/import_worker.rb b/app/workers/import_worker.rb
index d7c126f75bff1c0f2b5a2606218b3aaca10bae8b..aeb221cf688ec958bbceebed1c7cf21d8e32de41 100644
--- a/app/workers/import_worker.rb
+++ b/app/workers/import_worker.rb
@@ -37,6 +37,8 @@ class ImportWorker
   end
 
   def import_rows
-    CSV.new(import_contents).reject(&:blank?)
+    rows = CSV.new(import_contents).reject(&:blank?)
+    rows = rows.take(FollowLimitValidator.limit_for_account(@import.account)) if @import.type == 'following'
+    rows
   end
 end
diff --git a/app/workers/local_notification_worker.rb b/app/workers/local_notification_worker.rb
index 748270563c532a73f1ebf6bf3d7dff253d1e2ebb..48635e498fffd7e09893fd25ec92d509da241f0e 100644
--- a/app/workers/local_notification_worker.rb
+++ b/app/workers/local_notification_worker.rb
@@ -3,9 +3,16 @@
 class LocalNotificationWorker
   include Sidekiq::Worker
 
-  def perform(mention_id)
-    mention = Mention.find(mention_id)
-    NotifyService.new.call(mention.account, mention)
+  def perform(receiver_account_id, activity_id = nil, activity_class_name = nil)
+    if activity_id.nil? && activity_class_name.nil?
+      activity = Mention.find(receiver_account_id)
+      receiver = activity.account
+    else
+      receiver = Account.find(receiver_account_id)
+      activity = activity_class_name.constantize.find(activity_id)
+    end
+
+    NotifyService.new.call(receiver, activity)
   rescue ActiveRecord::RecordNotFound
     true
   end
diff --git a/app/workers/maintenance/destroy_media_worker.rb b/app/workers/maintenance/destroy_media_worker.rb
index 5f052983be6b42e5432cf474e7dad053fcf1b6fe..cde33d6d79a53df409cdb49c72ff7ea10e3e9351 100644
--- a/app/workers/maintenance/destroy_media_worker.rb
+++ b/app/workers/maintenance/destroy_media_worker.rb
@@ -6,7 +6,7 @@ class Maintenance::DestroyMediaWorker
   sidekiq_options queue: 'pull'
 
   def perform(media_attachment_id)
-    media = MediaAttachment.find(media_attachment_id)
+    media = media_attachment_id.is_a?(MediaAttachment) ? media_attachment_id : MediaAttachment.find(media_attachment_id)
     media.destroy
   rescue ActiveRecord::RecordNotFound
     true
diff --git a/app/workers/maintenance/redownload_account_media_worker.rb b/app/workers/maintenance/redownload_account_media_worker.rb
index fc26815f25e87f6bc2705b8a343a1f2d5b58b333..6afbe6e19cef35261697b5e92be3e1d438e36717 100644
--- a/app/workers/maintenance/redownload_account_media_worker.rb
+++ b/app/workers/maintenance/redownload_account_media_worker.rb
@@ -6,7 +6,7 @@ class Maintenance::RedownloadAccountMediaWorker
   sidekiq_options queue: 'pull', retry: false
 
   def perform(account_id)
-    account = Account.find(account_id)
+    account = account_id.is_a?(Account) ? account_id : Account.find(account_id)
     account.reset_avatar!
     account.reset_header!
     account.save
diff --git a/app/workers/maintenance/uncache_media_worker.rb b/app/workers/maintenance/uncache_media_worker.rb
index f6a51a1b8b274f75d42835a5858cbe732b48a08c..4bc62ef755c30e712420a494fd71a82fcf623b09 100644
--- a/app/workers/maintenance/uncache_media_worker.rb
+++ b/app/workers/maintenance/uncache_media_worker.rb
@@ -6,9 +6,9 @@ class Maintenance::UncacheMediaWorker
   sidekiq_options queue: 'pull'
 
   def perform(media_attachment_id)
-    media = MediaAttachment.find(media_attachment_id)
+    media = media_attachment_id.is_a?(MediaAttachment) ? media_attachment_id : MediaAttachment.find(media_attachment_id)
 
-    return unless media.file.exists?
+    return if media.file.blank?
 
     media.file.destroy
     media.save
diff --git a/app/workers/mute_worker.rb b/app/workers/mute_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7bf0923a5dbfb32b07dea86b665b2389279dcde3
--- /dev/null
+++ b/app/workers/mute_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class MuteWorker
+  include Sidekiq::Worker
+
+  def perform(account_id, target_account_id)
+    FeedManager.instance.clear_from_timeline(
+      Account.find(account_id),
+      Account.find(target_account_id)
+    )
+  end
+end
diff --git a/app/workers/publish_scheduled_status_worker.rb b/app/workers/publish_scheduled_status_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..850610c4e3cdb932dc16dd150a9a58d22039d44f
--- /dev/null
+++ b/app/workers/publish_scheduled_status_worker.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class PublishScheduledStatusWorker
+  include Sidekiq::Worker
+
+  sidekiq_options unique: :until_executed
+
+  def perform(scheduled_status_id)
+    scheduled_status = ScheduledStatus.find(scheduled_status_id)
+    scheduled_status.destroy!
+
+    PostStatusService.new.call(
+      scheduled_status.account,
+      options_with_objects(scheduled_status.params.with_indifferent_access)
+    )
+  rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid
+    true
+  end
+
+  def options_with_objects(options)
+    options.tap do |options_hash|
+      options_hash[:application] = Doorkeeper::Application.find(options_hash.delete(:application_id)) if options[:application_id]
+      options_hash[:thread]      = Status.find(options_hash.delete(:in_reply_to_id)) if options_hash[:in_reply_to_id]
+    end
+  end
+end
diff --git a/app/workers/push_conversation_worker.rb b/app/workers/push_conversation_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..16f5382152c2b29946450c23bf396a56c3c48f11
--- /dev/null
+++ b/app/workers/push_conversation_worker.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class PushConversationWorker
+  include Sidekiq::Worker
+
+  def perform(conversation_account_id)
+    conversation = AccountConversation.find(conversation_account_id)
+    message      = InlineRenderer.render(conversation, conversation.account, :conversation)
+    timeline_id  = "timeline:direct:#{conversation.account_id}"
+
+    Redis.current.publish(timeline_id, Oj.dump(event: :conversation, payload: message, queued_at: (Time.now.to_f * 1000.0).to_i))
+  rescue ActiveRecord::RecordNotFound
+    true
+  end
+end
diff --git a/app/workers/refollow_worker.rb b/app/workers/refollow_worker.rb
index 66bcd27c3e40c4816c262cb763fd19c710de744e..12f2bf671b83f9f9520f226e08ae169aa70013f9 100644
--- a/app/workers/refollow_worker.rb
+++ b/app/workers/refollow_worker.rb
@@ -9,7 +9,7 @@ class RefollowWorker
     target_account = Account.find(target_account_id)
     return unless target_account.protocol == :activitypub
 
-    target_account.followers.where(domain: nil).find_each do |follower|
+    target_account.followers.where(domain: nil).reorder(nil).find_each do |follower|
       # Locally unfollow remote account
       follower.unfollow!(target_account)
 
diff --git a/app/workers/scheduler/backup_cleanup_scheduler.rb b/app/workers/scheduler/backup_cleanup_scheduler.rb
index 5ab16c057da02defa504529ecf8a962fba09f29a..d436606999f1f5c5eac4bebceecdd5b510622871 100644
--- a/app/workers/scheduler/backup_cleanup_scheduler.rb
+++ b/app/workers/scheduler/backup_cleanup_scheduler.rb
@@ -3,8 +3,10 @@
 class Scheduler::BackupCleanupScheduler
   include Sidekiq::Worker
 
+  sidekiq_options unique: :until_executed, retry: 0
+
   def perform
-    old_backups.find_each(&:destroy!)
+    old_backups.reorder(nil).find_each(&:destroy!)
   end
 
   private
diff --git a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
index bab4ae8869b4dad834725e507750daadbc437581..e5e5f6bc42fcb035a3453442180d3529be3875fa 100644
--- a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
+++ b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
@@ -3,6 +3,8 @@
 class Scheduler::DoorkeeperCleanupScheduler
   include Sidekiq::Worker
 
+  sidekiq_options unique: :until_executed, retry: 0
+
   def perform
     Doorkeeper::AccessToken.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all
     Doorkeeper::AccessGrant.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all
diff --git a/app/workers/scheduler/email_scheduler.rb b/app/workers/scheduler/email_scheduler.rb
index 36866061b235b9ec4667f6f1e252dbb55e256be3..1eeeee412d7b12249f624090fe4b67e02bbb8b8c 100644
--- a/app/workers/scheduler/email_scheduler.rb
+++ b/app/workers/scheduler/email_scheduler.rb
@@ -3,8 +3,13 @@
 class Scheduler::EmailScheduler
   include Sidekiq::Worker
 
+  sidekiq_options unique: :until_executed, retry: 0
+
+  FREQUENCY      = 7.days.freeze
+  SIGN_IN_OFFSET = 1.day.freeze
+
   def perform
-    eligible_users.find_each do |user|
+    eligible_users.reorder(nil).find_each do |user|
       next unless user.allows_digest_emails?
       DigestMailerWorker.perform_async(user.id)
     end
@@ -13,11 +18,8 @@ class Scheduler::EmailScheduler
   private
 
   def eligible_users
-    User.confirmed
-        .joins(:account)
-        .where(accounts: { silenced: false, suspended: false })
-        .where(disabled: false)
-        .where('current_sign_in_at < ?', 20.days.ago)
-        .where('last_emailed_at IS NULL OR last_emailed_at < ?', 20.days.ago)
+    User.emailable
+        .where('current_sign_in_at < ?', (FREQUENCY + SIGN_IN_OFFSET).ago)
+        .where('last_emailed_at IS NULL OR last_emailed_at < ?', FREQUENCY.ago)
   end
 end
diff --git a/app/workers/scheduler/feed_cleanup_scheduler.rb b/app/workers/scheduler/feed_cleanup_scheduler.rb
index 42cf14128f2eec34b75dfcf734715a166d42f034..cd22734180572c8bd6151f00df95d6220af415de 100644
--- a/app/workers/scheduler/feed_cleanup_scheduler.rb
+++ b/app/workers/scheduler/feed_cleanup_scheduler.rb
@@ -3,6 +3,8 @@
 class Scheduler::FeedCleanupScheduler
   include Sidekiq::Worker
 
+  sidekiq_options unique: :until_executed, retry: 0
+
   def perform
     clean_home_feeds!
     clean_list_feeds!
diff --git a/app/workers/scheduler/ip_cleanup_scheduler.rb b/app/workers/scheduler/ip_cleanup_scheduler.rb
index 613a5e336d5e9079875bc26fabf3bc8ec2c4d7cb..42620332e7ee8cad0e42ae6622c0d96d1d59159c 100644
--- a/app/workers/scheduler/ip_cleanup_scheduler.rb
+++ b/app/workers/scheduler/ip_cleanup_scheduler.rb
@@ -5,6 +5,8 @@ class Scheduler::IpCleanupScheduler
 
   RETENTION_PERIOD = 1.year
 
+  sidekiq_options unique: :until_executed, retry: 0
+
   def perform
     time_ago = RETENTION_PERIOD.ago
     SessionActivation.where('updated_at < ?', time_ago).destroy_all
diff --git a/app/workers/scheduler/media_cleanup_scheduler.rb b/app/workers/scheduler/media_cleanup_scheduler.rb
index c35686fcb908b209d7de4905e25b537af1106b61..fb01aa70c9957237ebdd5fdfb02039e04f9fbc81 100644
--- a/app/workers/scheduler/media_cleanup_scheduler.rb
+++ b/app/workers/scheduler/media_cleanup_scheduler.rb
@@ -3,6 +3,8 @@
 class Scheduler::MediaCleanupScheduler
   include Sidekiq::Worker
 
+  sidekiq_options unique: :until_executed, retry: 0
+
   def perform
     unattached_media.find_each(&:destroy)
   end
diff --git a/app/workers/scheduler/pghero_scheduler.rb b/app/workers/scheduler/pghero_scheduler.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4453bf2cd0018b504d5dac83f0d0baf523172530
--- /dev/null
+++ b/app/workers/scheduler/pghero_scheduler.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class Scheduler::PgheroScheduler
+  include Sidekiq::Worker
+
+  sidekiq_options unique: :until_executed, retry: 0
+
+  def perform
+    PgHero.capture_space_stats
+  end
+end
diff --git a/app/workers/scheduler/scheduled_statuses_scheduler.rb b/app/workers/scheduler/scheduled_statuses_scheduler.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1772a246bc92dfd779f5d9168bd3efc4ba7ca806
--- /dev/null
+++ b/app/workers/scheduler/scheduled_statuses_scheduler.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Scheduler::ScheduledStatusesScheduler
+  include Sidekiq::Worker
+
+  sidekiq_options unique: :until_executed, retry: 0
+
+  def perform
+    due_statuses.find_each do |scheduled_status|
+      PublishScheduledStatusWorker.perform_at(scheduled_status.scheduled_at, scheduled_status.id)
+    end
+  end
+
+  private
+
+  def due_statuses
+    ScheduledStatus.where('scheduled_at <= ?', Time.now.utc + PostStatusService::MIN_SCHEDULE_OFFSET)
+  end
+end
diff --git a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb b/app/workers/scheduler/subscriptions_cleanup_scheduler.rb
index af2ae3120145127ffea83b012fd6cecd610adce3..5fba120f6ab339ccfede1b8b232a762b84f9f815 100644
--- a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb
+++ b/app/workers/scheduler/subscriptions_cleanup_scheduler.rb
@@ -3,6 +3,8 @@
 class Scheduler::SubscriptionsCleanupScheduler
   include Sidekiq::Worker
 
+  sidekiq_options unique: :until_executed, retry: 0
+
   def perform
     Subscription.expired.in_batches.delete_all
   end
diff --git a/app/workers/scheduler/subscriptions_scheduler.rb b/app/workers/scheduler/subscriptions_scheduler.rb
index dc16e85c228d0b28da129f72e9f90570b7c763ac..d5873bccb0ea2bfe9d392e827305a6e3a23b46b0 100644
--- a/app/workers/scheduler/subscriptions_scheduler.rb
+++ b/app/workers/scheduler/subscriptions_scheduler.rb
@@ -3,6 +3,8 @@
 class Scheduler::SubscriptionsScheduler
   include Sidekiq::Worker
 
+  sidekiq_options unique: :until_executed, retry: 0
+
   def perform
     Pubsubhubbub::SubscribeWorker.push_bulk(expiring_accounts.pluck(:id))
   end
diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb
index 245536ceac91d4bf6942b9e2905bf4fe9467f738..881b911be75c2b3967426432546e75852a4148ea 100644
--- a/app/workers/scheduler/user_cleanup_scheduler.rb
+++ b/app/workers/scheduler/user_cleanup_scheduler.rb
@@ -3,8 +3,10 @@
 class Scheduler::UserCleanupScheduler
   include Sidekiq::Worker
 
+  sidekiq_options unique: :until_executed, retry: 0
+
   def perform
-    User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).find_in_batches do |batch|
+    User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|
       Account.where(id: batch.map(&:account_id)).delete_all
       User.where(id: batch.map(&:id)).delete_all
     end
diff --git a/app/workers/unfollow_follow_worker.rb b/app/workers/unfollow_follow_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..50d3bf034adfb9acd9713465f921a7b6ffc245ef
--- /dev/null
+++ b/app/workers/unfollow_follow_worker.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class UnfollowFollowWorker
+  include Sidekiq::Worker
+
+  sidekiq_options queue: 'pull'
+
+  def perform(follower_account_id, old_target_account_id, new_target_account_id)
+    follower_account   = Account.find(follower_account_id)
+    old_target_account = Account.find(old_target_account_id)
+    new_target_account = Account.find(new_target_account_id)
+
+    FollowService.new.call(follower_account, new_target_account)
+    UnfollowService.new.call(follower_account, old_target_account)
+  rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
+    true
+  end
+end
diff --git a/app/workers/verify_account_links_worker.rb b/app/workers/verify_account_links_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..901498583e86dc19ed2f4881453051a183bda11f
--- /dev/null
+++ b/app/workers/verify_account_links_worker.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class VerifyAccountLinksWorker
+  include Sidekiq::Worker
+
+  sidekiq_options queue: 'pull', retry: false, unique: :until_executed
+
+  def perform(account_id)
+    account = Account.find(account_id)
+
+    account.fields.each do |field|
+      next unless !field.verified? && field.verifiable?
+      VerifyLinkService.new.call(field)
+    end
+
+    account.save! if account.changed?
+  rescue ActiveRecord::RecordNotFound
+    true
+  end
+end
diff --git a/app/workers/web/push_notification_worker.rb b/app/workers/web/push_notification_worker.rb
index 4a40e5c8bd98f49f1e7e8a281cad23fa9831fb00..8e8a359735674ea753a6b0fed60b5ab71f90cf9a 100644
--- a/app/workers/web/push_notification_worker.rb
+++ b/app/workers/web/push_notification_worker.rb
@@ -10,8 +10,8 @@ class Web::PushNotificationWorker
     notification = Notification.find(notification_id)
 
     subscription.push(notification) unless notification.activity.nil?
-  rescue Webpush::InvalidSubscription, Webpush::ExpiredSubscription
-    subscription.destroy!
+  rescue Webpush::ResponseError => e
+    subscription.destroy! if (400..499).cover?(e.response.code.to_i)
   rescue ActiveRecord::RecordNotFound
     true
   end
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..a506ad8ce6e27031c5f021fd6e771991fc323b16
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,65 @@
+module.exports = (api) => {
+  const env = api.env();
+
+  const envOptions = {
+    debug: false,
+    loose: true,
+    modules: false,
+  };
+
+  const config = {
+    presets: [
+      '@babel/react',
+      ['@babel/env', envOptions],
+    ],
+    plugins: [
+      '@babel/syntax-dynamic-import',
+      ['@babel/proposal-object-rest-spread', { useBuiltIns: true }],
+      ['@babel/proposal-decorators', { legacy: true }],
+      '@babel/proposal-class-properties',
+      ['react-intl', { messagesDir: './build/messages' }],
+      'preval',
+    ],
+  };
+
+  switch (env) {
+  case 'production':
+    envOptions.debug = false;
+    config.plugins.push(...[
+      'lodash',
+      [
+        'transform-react-remove-prop-types',
+        {
+          mode: 'remove',
+          removeImport: true,
+          additionalLibraries: [
+            'react-immutable-proptypes',
+          ],
+        },
+      ],
+      '@babel/transform-react-inline-elements',
+      [
+        '@babel/transform-runtime',
+        {
+          helpers: true,
+          regenerator: false,
+          useESModules: true,
+        },
+      ],
+    ]);
+    break;
+  case 'development':
+    envOptions.debug = true;
+    config.plugins.push(...[
+      '@babel/transform-react-jsx-source',
+      '@babel/transform-react-jsx-self',
+    ]);
+    break;
+  case 'test':
+    envOptions.modules = 'commonjs';
+    break;
+  }
+
+  return config;
+};
+
diff --git a/bin/tootctl b/bin/tootctl
new file mode 100755
index 0000000000000000000000000000000000000000..f26e1c7edcc43b90a93a45f97d22fbacaadd7d54
--- /dev/null
+++ b/bin/tootctl
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+APP_PATH = File.expand_path('../config/application', __dir__)
+require_relative '../config/boot'
+require_relative '../lib/cli'
+Mastodon::CLI.start(ARGV)
diff --git a/bin/webpack b/bin/webpack
index 0869ad277ef40ad05e67b7836532a469c7639fc8..465832722c9810c7b0dce67fdc1dacd6d8add213 100755
--- a/bin/webpack
+++ b/bin/webpack
@@ -1,7 +1,7 @@
 #!/usr/bin/env ruby
 
 ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
-ENV["NODE_ENV"]  ||= ENV["NODE_ENV"] || "development"
+ENV["NODE_ENV"]  ||= "development"
 
 require "pathname"
 ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
diff --git a/bin/webpack-dev-server b/bin/webpack-dev-server
index 251f65e8e3bb8f0dee4d2f14d3cd016f7421377f..faa69f078005c888e213e79159787b7a5e1015d1 100755
--- a/bin/webpack-dev-server
+++ b/bin/webpack-dev-server
@@ -1,7 +1,7 @@
 #!/usr/bin/env ruby
 
 ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
-ENV["NODE_ENV"]  ||= ENV["NODE_ENV"] || "development"
+ENV["NODE_ENV"]  ||= "development"
 
 require "pathname"
 ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
diff --git a/config/application.rb b/config/application.rb
index b100d7fccc18504afedd06d797552beacaf4eba1..b4a39b5c8a6014b6245eadb4207c1c083613fded 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -38,9 +38,12 @@ module Mastodon
     config.i18n.available_locales = [
       :en,
       :ar,
+      :ast,
       :bg,
       :ca,
       :co,
+      :cs,
+      :cy,
       :da,
       :de,
       :el,
@@ -59,6 +62,7 @@ module Mastodon
       :io,
       :it,
       :ja,
+      :ka,
       :ko,
       :nl,
       :no,
@@ -66,12 +70,14 @@ module Mastodon
       :pl,
       :pt,
       :'pt-BR',
+      :ro,
       :ru,
       :sk,
       :sl,
       :sr,
       :'sr-Latn',
       :sv,
+      :ta,
       :te,
       :th,
       :tr,
@@ -82,6 +88,7 @@ module Mastodon
     ]
 
     config.i18n.default_locale = ENV['DEFAULT_LOCALE']&.to_sym
+
     unless config.i18n.available_locales.include?(config.i18n.default_locale)
       config.i18n.default_locale = :en
     end
diff --git a/config/boot.rb b/config/boot.rb
index 0a3cd4ebee6728c0bd0519c4bd9abd609ff3f1b1..f3e36203aad90ff0b9874d6def3c6fa842941e0c 100644
--- a/config/boot.rb
+++ b/config/boot.rb
@@ -4,11 +4,11 @@ require 'bundler/setup' # Set up gems listed in the Gemfile.
 require 'bootsnap' # Speed up boot time by caching expensive operations.
 
 Bootsnap.setup(
-  cache_dir:            'tmp/cache',
-  development_mode:     ENV['RAILS_ENV'] == 'development',
+  cache_dir:            File.expand_path('../tmp/cache', __dir__),
+  development_mode:     ENV.fetch('RAILS_ENV', 'development') == 'development',
   load_path_cache:      true,
   autoload_paths_cache: true,
-  disable_trace:        true,
+  disable_trace:        false,
   compile_cache_iseq:   false,
   compile_cache_yaml:   false
 )
diff --git a/config/brakeman.ignore b/config/brakeman.ignore
index e8956639c30aa66bed47e0bb1d891a3954567ff8..58fb243da4589610d1da8f126ea2ad65b228ae78 100644
--- a/config/brakeman.ignore
+++ b/config/brakeman.ignore
@@ -1,5 +1,25 @@
 {
   "ignored_warnings": [
+    {
+      "warning_type": "SQL Injection",
+      "warning_code": 0,
+      "fingerprint": "04dbbc249b989db2e0119bbb0f59c9818e12889d2b97c529cdc0b1526002ba4b",
+      "check_name": "SQL",
+      "message": "Possible SQL injection",
+      "file": "app/models/report.rb",
+      "line": 90,
+      "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
+      "code": "Admin::ActionLog.from(\"(#{[Admin::ActionLog.where(:target_type => \"Report\", :target_id => id, :created_at => ((created_at..updated_at))).unscope(:order), Admin::ActionLog.where(:target_type => \"Account\", :target_id => target_account_id, :created_at => ((created_at..updated_at))).unscope(:order), Admin::ActionLog.where(:target_type => \"Status\", :target_id => status_ids, :created_at => ((created_at..updated_at))).unscope(:order)].map do\n \"(#{query.to_sql})\"\n end.join(\" UNION ALL \")}) AS admin_action_logs\")",
+      "render_path": null,
+      "location": {
+        "type": "method",
+        "class": "Report",
+        "method": "history"
+      },
+      "user_input": "Admin::ActionLog.where(:target_type => \"Status\", :target_id => status_ids, :created_at => ((created_at..updated_at))).unscope(:order)",
+      "confidence": "High",
+      "note": ""
+    },
     {
       "warning_type": "Cross-Site Scripting",
       "warning_code": 4,
@@ -7,8 +27,8 @@
       "check_name": "LinkToHref",
       "message": "Potentially unsafe model attribute in link_to href",
       "file": "app/views/admin/accounts/show.html.haml",
-      "line": 147,
-      "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
+      "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": {
@@ -19,6 +39,26 @@
       "confidence": "Weak",
       "note": ""
     },
+    {
+      "warning_type": "SQL Injection",
+      "warning_code": 0,
+      "fingerprint": "19df3740b8d02a9fe0eb52c939b4b87d3a2a591162a6adfa8d64e9c26aeebe6d",
+      "check_name": "SQL",
+      "message": "Possible SQL injection",
+      "file": "app/models/status.rb",
+      "line": 84,
+      "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,
+      "location": {
+        "type": "method",
+        "class": "Status",
+        "method": null
+      },
+      "user_input": "id",
+      "confidence": "Weak",
+      "note": ""
+    },
     {
       "warning_type": "Cross-Site Scripting",
       "warning_code": 4,
@@ -26,8 +66,8 @@
       "check_name": "LinkToHref",
       "message": "Potentially unsafe model attribute in link_to href",
       "file": "app/views/admin/accounts/show.html.haml",
-      "line": 153,
-      "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
+      "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": {
@@ -45,8 +85,8 @@
       "check_name": "LinkToHref",
       "message": "Potentially unsafe model attribute in link_to href",
       "file": "app/views/admin/accounts/show.html.haml",
-      "line": 57,
-      "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
+      "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": {
@@ -58,22 +98,23 @@
       "note": ""
     },
     {
-      "warning_type": "Dynamic Render Path",
-      "warning_code": 15,
-      "fingerprint": "44d3f14e05d8fbb5b23e13ac02f15aa38b2a2f0f03b9ba76bab7f98e155a4a4e",
-      "check_name": "Render",
-      "message": "Render path contains parameter value",
-      "file": "app/views/stream_entries/embed.html.haml",
-      "line": 3,
-      "link": "http://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 })",
-      "render_path": [{"type":"controller","class":"StatusesController","method":"embed","line":45,"file":"app/controllers/statuses_controller.rb"}],
+      "warning_type": "Mass Assignment",
+      "warning_code": 105,
+      "fingerprint": "28d81cc22580ef76e912b077b245f353499aa27b3826476667224c00227af2a9",
+      "check_name": "PermitAttributes",
+      "message": "Potentially dangerous key allowed for mass assignment",
+      "file": "app/controllers/admin/reports_controller.rb",
+      "line": 80,
+      "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
+      "code": "params.permit(:account_id, :resolved, :target_account_id)",
+      "render_path": null,
       "location": {
-        "type": "template",
-        "template": "stream_entries/embed"
+        "type": "method",
+        "class": "Admin::ReportsController",
+        "method": "filter_params"
       },
-      "user_input": "params[:id]",
-      "confidence": "Weak",
+      "user_input": ":account_id",
+      "confidence": "High",
       "note": ""
     },
     {
@@ -83,8 +124,8 @@
       "check_name": "Render",
       "message": "Render path contains parameter value",
       "file": "app/views/admin/action_logs/index.html.haml",
-      "line": 5,
-      "link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
+      "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"}],
       "location": {
@@ -95,6 +136,26 @@
       "confidence": "Weak",
       "note": ""
     },
+    {
+      "warning_type": "Redirect",
+      "warning_code": 18,
+      "fingerprint": "5fad11cd67f905fab9b1d5739d01384a1748ebe78c5af5ac31518201925265a7",
+      "check_name": "Redirect",
+      "message": "Possible unprotected redirect",
+      "file": "app/controllers/remote_interaction_controller.rb",
+      "line": 20,
+      "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,
+      "location": {
+        "type": "method",
+        "class": "RemoteInteractionController",
+        "method": "create"
+      },
+      "user_input": "RemoteFollow.new(resource_params).interact_address_for(Status.find(params[:id]))",
+      "confidence": "High",
+      "note": ""
+    },
     {
       "warning_type": "Cross-Site Scripting",
       "warning_code": 4,
@@ -102,8 +163,8 @@
       "check_name": "LinkToHref",
       "message": "Potentially unsafe model attribute in link_to href",
       "file": "app/views/admin/accounts/show.html.haml",
-      "line": 156,
-      "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
+      "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": {
@@ -114,6 +175,45 @@
       "confidence": "Weak",
       "note": ""
     },
+    {
+      "warning_type": "Dynamic Render Path",
+      "warning_code": 15,
+      "fingerprint": "67afc0d5f7775fa5bd91d1912e1b5505aeedef61876347546fa20f92fd6915e6",
+      "check_name": "Render",
+      "message": "Render path contains parameter value",
+      "file": "app/views/stream_entries/embed.html.haml",
+      "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"}],
+      "location": {
+        "type": "template",
+        "template": "stream_entries/embed"
+      },
+      "user_input": "params[:id]",
+      "confidence": "Weak",
+      "note": ""
+    },
+    {
+      "warning_type": "SQL Injection",
+      "warning_code": 0,
+      "fingerprint": "6f075c1484908e3ec9bed21ab7cf3c7866be8da3881485d1c82e13093aefcbd7",
+      "check_name": "SQL",
+      "message": "Possible SQL injection",
+      "file": "app/models/status.rb",
+      "line": 89,
+      "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,
+      "location": {
+        "type": "method",
+        "class": "Status",
+        "method": null
+      },
+      "user_input": "id",
+      "confidence": "Weak",
+      "note": ""
+    },
     {
       "warning_type": "Cross-Site Scripting",
       "warning_code": 4,
@@ -121,8 +221,8 @@
       "check_name": "LinkToHref",
       "message": "Potentially unsafe model attribute in link_to href",
       "file": "app/views/admin/accounts/show.html.haml",
-      "line": 130,
-      "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
+      "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": {
@@ -141,7 +241,7 @@
       "message": "Render path contains parameter value",
       "file": "app/views/admin/custom_emojis/index.html.haml",
       "line": 45,
-      "link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
+      "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"}],
       "location": {
@@ -160,7 +260,7 @@
       "message": "Possible SQL injection",
       "file": "lib/mastodon/snowflake.rb",
       "line": 87,
-      "link": "http://brakemanscanner.org/docs/warning_types/sql_injection/",
+      "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
       "code": "connection.execute(\"        CREATE OR REPLACE FUNCTION timestamp_id(table_name text)\\n        RETURNS bigint AS\\n        $$\\n          DECLARE\\n            time_part bigint;\\n            sequence_base bigint;\\n            tail bigint;\\n          BEGIN\\n            time_part := (\\n              -- Get the time in milliseconds\\n              ((date_part('epoch', now()) * 1000))::bigint\\n              -- And shift it over two bytes\\n              << 16);\\n\\n            sequence_base := (\\n              'x' ||\\n              -- Take the first two bytes (four hex characters)\\n              substr(\\n                -- Of the MD5 hash of the data we documented\\n                md5(table_name ||\\n                  '#{SecureRandom.hex(16)}' ||\\n                  time_part::text\\n                ),\\n                1, 4\\n              )\\n            -- And turn it into a bigint\\n            )::bit(16)::bigint;\\n\\n            -- Finally, add our sequence number to our base, and chop\\n            -- it to the last two bytes\\n            tail := (\\n              (sequence_base + nextval(table_name || '_id_seq'))\\n              & 65535);\\n\\n            -- Return the time part and the sequence part. OR appears\\n            -- faster here than addition, but they're equivalent:\\n            -- time_part has no trailing two bytes, and tail is only\\n            -- the last two bytes.\\n            RETURN time_part | tail;\\n          END\\n        $$ LANGUAGE plpgsql VOLATILE;\\n\")",
       "render_path": null,
       "location": {
@@ -180,7 +280,7 @@
       "message": "Render path contains parameter value",
       "file": "app/views/admin/accounts/index.html.haml",
       "line": 67,
-      "link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
+      "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"}],
       "location": {
@@ -191,25 +291,6 @@
       "confidence": "Weak",
       "note": ""
     },
-    {
-      "warning_type": "Cross-Site Request Forgery",
-      "warning_code": 7,
-      "fingerprint": "ab491f72606337a348482d006eb67a3b1616685fd48644d5ac909bbcd62a5000",
-      "check_name": "ForgerySetting",
-      "message": "'protect_from_forgery' should be called in WellKnown::HostMetaController",
-      "file": "app/controllers/well_known/host_meta_controller.rb",
-      "line": 4,
-      "link": "http://brakemanscanner.org/docs/warning_types/cross-site_request_forgery/",
-      "code": null,
-      "render_path": null,
-      "location": {
-        "type": "controller",
-        "controller": "WellKnown::HostMetaController"
-      },
-      "user_input": null,
-      "confidence": "High",
-      "note": ""
-    },
     {
       "warning_type": "Redirect",
       "warning_code": 18,
@@ -218,7 +299,7 @@
       "message": "Possible unprotected redirect",
       "file": "app/controllers/media_controller.rb",
       "line": 10,
-      "link": "http://brakemanscanner.org/docs/warning_types/redirect/",
+      "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,
       "location": {
@@ -237,8 +318,8 @@
       "check_name": "LinkToHref",
       "message": "Potentially unsafe model attribute in link_to href",
       "file": "app/views/admin/accounts/show.html.haml",
-      "line": 119,
-      "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
+      "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": {
@@ -256,8 +337,8 @@
       "check_name": "Redirect",
       "message": "Possible unprotected redirect",
       "file": "app/controllers/remote_follow_controller.rb",
-      "line": 18,
-      "link": "http://brakemanscanner.org/docs/warning_types/redirect/",
+      "line": 19,
+      "link": "https://brakemanscanner.org/docs/warning_types/redirect/",
       "code": "redirect_to(RemoteFollow.new(resource_params).subscribe_address_for(Account.find_local!(params[:account_username])))",
       "render_path": null,
       "location": {
@@ -269,44 +350,6 @@
       "confidence": "High",
       "note": ""
     },
-    {
-      "warning_type": "Dynamic Render Path",
-      "warning_code": 15,
-      "fingerprint": "c5d6945d63264af106d49367228d206aa2f176699ecdce2b98fac101bc6a96cf",
-      "check_name": "Render",
-      "message": "Render path contains parameter value",
-      "file": "app/views/admin/reports/index.html.haml",
-      "line": 25,
-      "link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
-      "code": "render(action => filtered_reports.page(params[:page]), {})",
-      "render_path": [{"type":"controller","class":"Admin::ReportsController","method":"index","line":10,"file":"app/controllers/admin/reports_controller.rb"}],
-      "location": {
-        "type": "template",
-        "template": "admin/reports/index"
-      },
-      "user_input": "params[:page]",
-      "confidence": "Weak",
-      "note": ""
-    },
-    {
-      "warning_type": "Cross-Site Request Forgery",
-      "warning_code": 7,
-      "fingerprint": "d4278f04e807ec58a23925f8ab31fad5e84692f2fb9f2f57e7931aff05d57cf8",
-      "check_name": "ForgerySetting",
-      "message": "'protect_from_forgery' should be called in WellKnown::WebfingerController",
-      "file": "app/controllers/well_known/webfinger_controller.rb",
-      "line": 4,
-      "link": "http://brakemanscanner.org/docs/warning_types/cross-site_request_forgery/",
-      "code": null,
-      "render_path": null,
-      "location": {
-        "type": "controller",
-        "controller": "WellKnown::WebfingerController"
-      },
-      "user_input": null,
-      "confidence": "High",
-      "note": ""
-    },
     {
       "warning_type": "Cross-Site Scripting",
       "warning_code": 4,
@@ -314,8 +357,8 @@
       "check_name": "LinkToHref",
       "message": "Potentially unsafe model attribute in link_to href",
       "file": "app/views/admin/accounts/show.html.haml",
-      "line": 150,
-      "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
+      "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": {
@@ -326,6 +369,26 @@
       "confidence": "Weak",
       "note": ""
     },
+    {
+      "warning_type": "Mass Assignment",
+      "warning_code": 105,
+      "fingerprint": "e867661b2c9812bc8b75a5df12b28e2a53ab97015de0638b4e732fe442561b28",
+      "check_name": "PermitAttributes",
+      "message": "Potentially dangerous key allowed for mass assignment",
+      "file": "app/controllers/api/v1/reports_controller.rb",
+      "line": 37,
+      "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
+      "code": "params.permit(:account_id, :comment, :forward, :status_ids => ([]))",
+      "render_path": null,
+      "location": {
+        "type": "method",
+        "class": "Api::V1::ReportsController",
+        "method": "report_params"
+      },
+      "user_input": ":account_id",
+      "confidence": "High",
+      "note": ""
+    },
     {
       "warning_type": "Dynamic Render Path",
       "warning_code": 15,
@@ -333,10 +396,10 @@
       "check_name": "Render",
       "message": "Render path contains parameter value",
       "file": "app/views/stream_entries/show.html.haml",
-      "line": 24,
-      "link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
+      "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":22,"file":"app/controllers/statuses_controller.rb"}],
+      "render_path": [{"type":"controller","class":"StatusesController","method":"show","line":30,"file":"app/controllers/statuses_controller.rb"}],
       "location": {
         "type": "template",
         "template": "stream_entries/show"
@@ -346,6 +409,6 @@
       "note": ""
     }
   ],
-  "updated": "2018-02-16 06:42:53 +0100",
-  "brakeman_version": "4.0.1"
+  "updated": "2018-10-20 23:24:45 +1300",
+  "brakeman_version": "4.2.1"
 }
diff --git a/config/deploy.rb b/config/deploy.rb
index e0cd60f5438273a72576a12fe76dd371a450ecfa..f0db50788c26b6c602dce3d2a907c3941898bb73 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-lock '3.10.2'
+lock '3.11.0'
 
 set :repo_url, ENV.fetch('REPO', 'https://github.com/tootsuite/mastodon.git')
 set :branch, ENV.fetch('BRANCH', 'master')
diff --git a/config/environments/development.rb b/config/environments/development.rb
index b6478f16e40c1db43e5173a4f195bb2f0977f5bd..0791b82ab6ea1393efcb3faff300d998c2ee7fa1 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -87,7 +87,7 @@ Rails.application.configure do
   config.x.otp_secret = ENV.fetch('OTP_SECRET', '1fc2b87989afa6351912abeebe31ffc5c476ead9bf8b3d74cbc4a302c7b69a45b40b1bbef3506ddad73e942e15ed5ca4b402bf9a66423626051104f4b5f05109')
 end
 
-ActiveRecordQueryTrace.enabled = ENV.fetch('QUERY_TRACE_ENABLED') { false }
+ActiveRecordQueryTrace.enabled = ENV['QUERY_TRACE_ENABLED'] == 'true'
 
 module PrivateAddressCheck
   def self.private_address?(*)
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 30239671c08c0a1a205f0310d41d84b7347de906..70baa6ad1a7b7d993f8a08989487e8bda723510f 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -13,7 +13,7 @@ Rails.application.configure do
   # Full error reports are disabled and caching is turned on.
   config.consider_all_requests_local       = false
   config.action_controller.perform_caching = true
-  config.action_controller.asset_host      = ENV['CDN_HOST'] if ENV.key?('CDN_HOST')
+  config.action_controller.asset_host      = ENV['CDN_HOST'] if ENV['CDN_HOST'].present?
 
   # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
   # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
@@ -42,7 +42,7 @@ Rails.application.configure do
   config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
 
   # Allow to specify public IP of reverse proxy if it's needed
-  config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split.map { |item| IPAddr.new(item) } unless ENV['TRUSTED_PROXY_IP'].blank?
+  config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split.map { |item| IPAddr.new(item) } if ENV['TRUSTED_PROXY_IP'].present?
 
   # Use the lowest log level to ensure availability of diagnostic information
   # when problems arise.
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 1c1891561fd8072e6617d876e0b049744fac785b..a35cadcfa30e608228686a07d95022a3ebaffeda 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -23,7 +23,7 @@ Rails.application.configure do
   config.consider_all_requests_local       = true
   config.action_controller.perform_caching = false
 
-  # The default store, file_store is shared by processses parallely executed
+  # The default store, file_store is shared by processes parallelly executed
   # and should not be used.
   config.cache_store = :memory_store
 
diff --git a/config/initializers/0_post_deployment_migrations.rb b/config/initializers/0_post_deployment_migrations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..61121ccd70a188dc8a260ba2d79b1eb058481c32
--- /dev/null
+++ b/config/initializers/0_post_deployment_migrations.rb
@@ -0,0 +1,15 @@
+# Post deployment migrations are included by default. This file must be loaded
+# before other initializers as Rails may otherwise memoize a list of migrations
+# excluding the post deployment migrations.
+
+unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS']
+  Rails.application.config.paths['db'].each do |db_path|
+    path = Rails.root.join(db_path, 'post_migrate').to_s
+
+    Rails.application.config.paths['db/migrate'] << path
+
+    # Rails memoizes migrations at certain points where it won't read the above
+    # path just yet. As such we must also update the following list of paths.
+    ActiveRecord::Migrator.migrations_paths << path
+  end
+end
diff --git a/config/initializers/ostatus.rb b/config/initializers/1_hosts.rb
similarity index 93%
rename from config/initializers/ostatus.rb
rename to config/initializers/1_hosts.rb
index 5773b72903905800483205112166ed638a4c7446..757f1f73554568a447356d6adc918e7677bfc317 100644
--- a/config/initializers/ostatus.rb
+++ b/config/initializers/1_hosts.rb
@@ -7,7 +7,7 @@ web_host = ENV.fetch('WEB_DOMAIN') { host }
 alternate_domains = ENV.fetch('ALTERNATE_DOMAINS') { '' }
 
 Rails.application.configure do
-  https    = Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true'
+  https = Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true'
 
   config.x.local_domain = host
   config.x.web_domain   = web_host
diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb
index 37f2c0d45053eed901fa43171c95e803449a4a03..59cfbba173c33606540ae0e21b3bd7263d867ef1 100644
--- a/config/initializers/content_security_policy.rb
+++ b/config/initializers/content_security_policy.rb
@@ -2,17 +2,31 @@
 # For further information see the following documentation
 # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
 
-# Rails.application.config.content_security_policy do |p|
-#   p.default_src :self, :https
-#   p.font_src    :self, :https, :data
-#   p.img_src     :self, :https, :data
-#   p.object_src  :none
-#   p.script_src  :self, :https
-#   p.style_src   :self, :https, :unsafe_inline
-#
-#   # Specify URI for violation reports
-#   # p.report_uri "/csp-violation-report-endpoint"
-# end
+base_host     = Rails.configuration.x.web_domain
+assets_host   = Rails.configuration.action_controller.asset_host
+assets_host ||= "http#{Rails.configuration.x.use_https ? 's' : ''}://#{base_host}"
+
+Rails.application.config.content_security_policy do |p|
+  p.base_uri        :none
+  p.default_src     :none
+  p.frame_ancestors :none
+  p.font_src        :self, assets_host
+  p.img_src         :self, :https, :data, :blob, assets_host
+  p.style_src       :self, :unsafe_inline, assets_host
+  p.media_src       :self, :https, :data, assets_host
+  p.frame_src       :self, :https
+  p.manifest_src    :self, assets_host
+
+  if Rails.env.development?
+    webpacker_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{Webpacker.dev_server.host_with_port}" }
+
+    p.connect_src :self, :blob, assets_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls
+    p.script_src  :self, :unsafe_inline, :unsafe_eval, assets_host
+  else
+    p.connect_src :self, :blob, assets_host, Rails.configuration.x.streaming_api_base_url
+    p.script_src  :self, assets_host
+  end
+end
 
 # Report CSP violations to a specified URI
 # For further information see the following documentation:
diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb
index 681a7498f969b702f4a888c434d0fdc5bce7ac0b..55f8c9c9193c8387770f1e62fdc2b4c1810b8710 100644
--- a/config/initializers/cors.rb
+++ b/config/initializers/cors.rb
@@ -9,10 +9,18 @@ Rails.application.config.middleware.insert_before 0, Rack::Cors do
   allow do
     origins '*'
 
+    resource '/.well-known/*',
+      headers: :any,
+      methods: [:get],
+      credentials: false
     resource '/@:username',
       headers: :any,
       methods: [:get],
       credentials: false
+    resource '/users/:username',
+      headers: :any,
+      methods: [:get],
+      credentials: false
     resource '/api/*',
       headers: :any,
       methods: [:post, :put, :delete, :get, :patch, :options],
diff --git a/config/initializers/delivery_job.rb b/config/initializers/delivery_job.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cc29272729dde267958d7b84c8828c4a4f2b0360
--- /dev/null
+++ b/config/initializers/delivery_job.rb
@@ -0,0 +1,3 @@
+ActionMailer::DeliveryJob.class_eval do
+  discard_on ActiveJob::DeserializationError
+end
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index e0d263f16f6cc153099a083bf2036c3db70d5774..cd9bacf68033e609abf0e662b9958b8b00555499 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -9,6 +9,7 @@ Warden::Manager.after_set_user except: :fetch do |user, warden|
     value: session_id,
     expires: 1.year.from_now,
     httponly: true,
+    secure: (Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true'),
   }
 end
 
@@ -18,6 +19,7 @@ Warden::Manager.after_fetch do |user, warden|
       value: warden.cookies.signed['_session_id'] || warden.raw_session['auth_id'],
       expires: 1.year.from_now,
       httponly: true,
+      secure: (Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true'),
     }
   else
     warden.logout
@@ -57,6 +59,8 @@ module Devise
   @@ldap_password = nil
   mattr_accessor :ldap_tls_no_verify
   @@ldap_tls_no_verify = false
+  mattr_accessor :ldap_search_filter
+  @@ldap_search_filter = nil
 
   class Strategies::PamAuthenticatable
     def valid?
@@ -360,5 +364,6 @@ Devise.setup do |config|
     config.ldap_password       = ENV.fetch('LDAP_PASSWORD')
     config.ldap_uid            = ENV.fetch('LDAP_UID', 'cn')
     config.ldap_tls_no_verify  = ENV['LDAP_TLS_NO_VERIFY'] == 'true'
+    config.ldap_search_filter  = ENV.fetch('LDAP_SEARCH_FILTER', '%{uid}=%{email}')
   end
 end
diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb
index fe2490b326ababd31221d4b4a1662d8c3a274572..367eead6a40ebd27044459a116bd12d795694c8c 100644
--- a/config/initializers/doorkeeper.rb
+++ b/config/initializers/doorkeeper.rb
@@ -58,6 +58,7 @@ Doorkeeper.configure do
   optional_scopes :write,
                   :'write:accounts',
                   :'write:blocks',
+                  :'write:conversations',
                   :'write:favourites',
                   :'write:filters',
                   :'write:follows',
@@ -76,7 +77,6 @@ Doorkeeper.configure do
                   :'read:lists',
                   :'read:mutes',
                   :'read:notifications',
-                  :'read:reports',
                   :'read:search',
                   :'read:statuses',
                   :follow,
diff --git a/config/initializers/ffmpeg.rb b/config/initializers/ffmpeg.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4c0bf779d88992cfbde11f160057340651c1de8c
--- /dev/null
+++ b/config/initializers/ffmpeg.rb
@@ -0,0 +1,3 @@
+if ENV['FFMPEG_BINARY'].present?
+    FFMPEG.ffmpeg_binary = ENV['FFMPEG_BINARY']
+end
diff --git a/config/initializers/http_client_proxy.rb b/config/initializers/http_client_proxy.rb
index e607aff3c406addd93413f8954d95defc4c52cb6..9d7b16e69c87a671b53cf57440e0b5cfcaceeadd 100644
--- a/config/initializers/http_client_proxy.rb
+++ b/config/initializers/http_client_proxy.rb
@@ -6,7 +6,7 @@ Rails.application.configure do
     raise "No proxy host" unless proxy.host
 
     host = proxy.host
-    host = host[1...-1] if host[0] == '[' #for IPv6 address
+    host = host[1...-1] if host[0] == '[' # for IPv6 address
     config.x.http_client_proxy[:proxy] = { proxy_address: host, proxy_port: proxy.port, proxy_username: proxy.user, proxy_password: proxy.password }.compact
   end
 
diff --git a/config/initializers/json_ld.rb b/config/initializers/json_ld.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d5575d135464f18fddbed4cd8353b3d59044c1d1
--- /dev/null
+++ b/config/initializers/json_ld.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+require_relative '../../lib/json_ld/security'
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index 85fb812506066f461eb36c09a84c4767895128c6..254e751d42ea93f4d3f98a9638ae25cbeb22b66f 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -3,7 +3,7 @@ Rails.application.config.middleware.use OmniAuth::Builder do
 end
 
 Devise.setup do |config|
-  # Devise omniauth strategies
+  # Devise omniauth strategies
   options = {}
   options[:redirect_at_sign_in] = ENV['OAUTH_REDIRECT_AT_SIGN_IN'] == 'true'
 
@@ -38,7 +38,7 @@ Devise.setup do |config|
     saml_options = options
     saml_options[:assertion_consumer_service_url] = ENV['SAML_ACS_URL'] if ENV['SAML_ACS_URL']
     saml_options[:issuer] = ENV['SAML_ISSUER'] if ENV['SAML_ISSUER']
-    saml_options[:idp_sso_target_url] = ENV['SAML_IDP_SSO_TARGET_URL']  if ENV['SAML_IDP_SSO_TARGET_URL']
+    saml_options[:idp_sso_target_url] = ENV['SAML_IDP_SSO_TARGET_URL'] if ENV['SAML_IDP_SSO_TARGET_URL']
     saml_options[:idp_sso_target_url_runtime_params] = ENV['SAML_IDP_SSO_TARGET_PARAMS'] if ENV['SAML_IDP_SSO_TARGET_PARAMS'] # FIXME: Should be parsable Hash
     saml_options[:idp_cert] = ENV['SAML_IDP_CERT'] if ENV['SAML_IDP_CERT']
     saml_options[:idp_cert_fingerprint] = ENV['SAML_IDP_CERT_FINGERPRINT'] if ENV['SAML_IDP_CERT_FINGERPRINT']
@@ -62,5 +62,4 @@ Devise.setup do |config|
     saml_options[:uid_attribute] = ENV['SAML_UID_ATTRIBUTE'] if ENV['SAML_UID_ATTRIBUTE']
     config.omniauth :saml, saml_options
   end
-
 end
diff --git a/config/initializers/open_uri_redirection.rb b/config/initializers/open_uri_redirection.rb
index e24fdecabc0e457f4a75d33d6e0e2deefacd3506..e9de85bdc54e4efedd04bb0b74c645644756ec53 100644
--- a/config/initializers/open_uri_redirection.rb
+++ b/config/initializers/open_uri_redirection.rb
@@ -1,8 +1,8 @@
 require 'open-uri'
 
 module OpenURI
-  def OpenURI.redirectable?(uri1, uri2) # :nodoc:
-    uri1.scheme.downcase == uri2.scheme.downcase ||
+  def self.redirectable?(uri1, uri2) # :nodoc:
+    uri1.scheme.casecmp(uri2.scheme).zero? ||
       (/\A(?:http|https|ftp)\z/i =~ uri1.scheme && /\A(?:http|https|ftp)\z/i =~ uri2.scheme)
   end
 end
diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb
index c134bc5b8feb00e29a1044d9423a8edfd4d25c23..ce4185e024dbf92e7c02357e0dd37276a948ed3d 100644
--- a/config/initializers/paperclip.rb
+++ b/config/initializers/paperclip.rb
@@ -25,7 +25,7 @@ if ENV['S3_ENABLED'] == 'true'
     s3_protocol: s3_protocol,
     s3_host_name: s3_hostname,
     s3_headers: {
-      'Cache-Control' => 'max-age=315576000',
+      'Cache-Control' => 'public, max-age=315576000, immutable',
     },
     s3_permissions: ENV.fetch('S3_PERMISSION') { 'public-read' },
     s3_region: s3_region,
@@ -36,6 +36,9 @@ if ENV['S3_ENABLED'] == 'true'
     },
     s3_options: {
       signature_version: ENV.fetch('S3_SIGNATURE_VERSION') { 'v4' },
+      http_open_timeout: 5,
+      http_read_timeout: 5,
+      http_idle_timeout: 5,
     }
   )
 
@@ -47,10 +50,10 @@ if ENV['S3_ENABLED'] == 'true'
     Paperclip::Attachment.default_options[:url] = ':s3_path_url'
   end
 
-  if ENV.has_key?('S3_CLOUDFRONT_HOST')
+  if ENV.has_key?('S3_ALIAS_HOST') || ENV.has_key?('S3_CLOUDFRONT_HOST')
     Paperclip::Attachment.default_options.merge!(
       url: ':s3_alias_url',
-      s3_host_alias: ENV['S3_CLOUDFRONT_HOST']
+      s3_host_alias: ENV['S3_ALIAS_HOST'] || ENV['S3_CLOUDFRONT_HOST']
     )
   end
 elsif ENV['SWIFT_ENABLED'] == 'true'
@@ -74,14 +77,10 @@ elsif ENV['SWIFT_ENABLED'] == 'true'
     fog_public: true
   )
 else
-  require 'fog/local'
-
   Paperclip::Attachment.default_options.merge!(
-    fog_credentials: {
-      provider: 'Local',
-      local_root: ENV.fetch('PAPERCLIP_ROOT_PATH') { Rails.root.join('public', 'system') },
-    },
-    fog_directory: '',
-    fog_host: ENV.fetch('PAPERCLIP_ROOT_URL') { '/system' }
+    storage: :filesystem,
+    use_timestamp: true,
+    path: (ENV['PAPERCLIP_ROOT_PATH'] || ':rails_root/public/system') + '/:class/:attachment/:id_partition/:style/:filename',
+    url: (ENV['PAPERCLIP_ROOT_URL'] || '/system') + '/:class/:attachment/:id_partition/:style/:filename',
   )
 end
diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb
index 0ca0a7e7fd526679ac3f769df7f9634e0e99f20b..35302e37b1be76c7d35291fc31342a98af09b97f 100644
--- a/config/initializers/rack_attack.rb
+++ b/config/initializers/rack_attack.rb
@@ -42,7 +42,7 @@ class Rack::Attack
   # (blocklist & throttles are skipped)
   Rack::Attack.safelist('allow from localhost') do |req|
     # Requests are allowed if the return value is truthy
-    '127.0.0.1' == req.ip || '::1' == req.ip
+    req.ip == '127.0.0.1' || req.ip == '::1'
   end
 
   throttle('throttle_authenticated_api', limit: 300, period: 5.minutes) do |req|
@@ -57,6 +57,10 @@ class Rack::Attack
     req.authenticated_user_id if req.post? && req.path.start_with?('/api/v1/media')
   end
 
+  throttle('throttle_api_sign_up', limit: 5, period: 30.minutes) do |req|
+    req.ip if req.post? && req.path == '/api/v1/accounts'
+  end
+
   throttle('protected_paths', limit: 25, period: 5.minutes) do |req|
     req.ip if req.post? && req.path =~ PROTECTED_PATHS_REGEX
   end
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index 05c804100564f491e9f45bd6a98e747b0ec6a7b6..7f8a40d7ba7684e8589d9b5c2a1c51653f44220f 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -19,4 +19,4 @@ Sidekiq.configure_client do |config|
   config.redis = redis_params
 end
 
-Sidekiq::Logging.logger.level = ::Logger::const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s)
+Sidekiq::Logging.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s)
diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb
index 5983918cd420ff6cd0e410ce805c0daf1e3dad1a..386ede654c62d26395a6dd1dde9e2fd3f2f4381f 100644
--- a/config/initializers/simple_form.rb
+++ b/config/initializers/simple_form.rb
@@ -1,4 +1,15 @@
 # Use this setup block to configure all options available in SimpleForm.
+
+module AppendComponent
+  def append(wrapper_options = nil)
+    @append ||= begin
+      options[:append].to_s.html_safe if options[:append].present?
+    end
+  end
+end
+
+SimpleForm.include_component(AppendComponent)
+
 SimpleForm.setup do |config|
   # Wrappers are used by the form builder to generate a
   # complete input. You can remove any component from the
@@ -52,6 +63,22 @@ SimpleForm.setup do |config|
 
   config.wrappers :with_label, class: [:input, :with_label], hint_class: :field_with_hint, error_class: :field_with_errors do |b|
     b.use :html5
+
+    b.wrapper tag: :div, class: :label_input do |ba|
+      ba.use :label
+
+      ba.wrapper tag: :div, class: :label_input__wrapper do |bb|
+        bb.use :input
+        bb.optional :append, wrap_with: { tag: :div, class: 'label_input__append' }
+      end
+    end
+
+    b.use :hint,  wrap_with: { tag: :span, class: :hint }
+    b.use :error, wrap_with: { tag: :span, class: :error }
+  end
+
+  config.wrappers :with_floating_label, class: [:input, :with_floating_label], hint_class: :field_with_hint, error_class: :field_with_errors do |b|
+    b.use :html5
     b.use :label_input, wrap_with: { tag: :div, class: :label_input }
     b.use :hint,  wrap_with: { tag: :span, class: :hint }
     b.use :error, wrap_with: { tag: :span, class: :error }
@@ -111,12 +138,12 @@ SimpleForm.setup do |config|
   # config.item_wrapper_class = nil
 
   # How the label text should be generated altogether with the required text.
-  # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
+  config.label_text = lambda { |label, required, explicit_label| "#{label} #{required}" }
 
   # You can define the class to use on all labels. Default is nil.
   # config.label_class = nil
 
-  # You can define the default class to be used on forms. Can be overriden
+  # You can define the default class to be used on forms. Can be overridden
   # with `html: { :class }`. Defaulting to none.
   # config.default_form_class = nil
 
diff --git a/config/initializers/statsd.rb b/config/initializers/statsd.rb
index 45702ac94de671b14563ce1de24ee2646832a66f..ce83fd9de2d484aec51dbcc223081d427559a3de 100644
--- a/config/initializers/statsd.rb
+++ b/config/initializers/statsd.rb
@@ -9,7 +9,7 @@ if ENV['STATSD_ADDR'].present?
   ::NSA.inform_statsd(statsd) do |informant|
     informant.collect(:action_controller, :web)
     informant.collect(:active_record, :db)
-    informant.collect(:cache, :cache)
+    informant.collect(:active_support_cache, :cache)
     informant.collect(:sidekiq, :sidekiq)
   end
 end
diff --git a/config/initializers/twitter_regex.rb b/config/initializers/twitter_regex.rb
index c227f92d3ead98b247e8c1c47e60b43e10c0316e..0e8f5bfeb47353d1c151e8917f03650e000067b6 100644
--- a/config/initializers/twitter_regex.rb
+++ b/config/initializers/twitter_regex.rb
@@ -1,6 +1,5 @@
 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_url_balanced_parens] = /
@@ -28,7 +27,7 @@ module Twitter
     )/iox
     REGEXEN[:valid_url] = %r{
       (                                                                                     #   $1 total match
-        (#{REGEXEN[:valid_url_preceding_chars]})                                            #   $2 Preceeding chracter
+        (#{REGEXEN[:valid_url_preceding_chars]})                                            #   $2 Preceding character
         (                                                                                   #   $3 URL
           ((https?|dat|dweb|ipfs|ipns|ssb|gopher):\/\/)?                                    #   $4 Protocol (optional)
           (#{REGEXEN[:valid_domain]})                                                       #   $5 Domain(s)
diff --git a/config/initializers/vapid.rb b/config/initializers/vapid.rb
index 618f5a3fbbd1f056d510af1933baf051bc4faf35..7dd870c8b7d9afe3824752f167774f1ed16229cf 100644
--- a/config/initializers/vapid.rb
+++ b/config/initializers/vapid.rb
@@ -1,7 +1,6 @@
 # frozen_string_literal: true
 
 Rails.application.configure do
-
   # You can generate the keys using the following command (first is the private key, second is the public one)
   # You should only generate this once per instance. If you later decide to change it, all push subscription will
   # be invalidated, requiring the users to access the website again to resubscribe.
diff --git a/config/locales/activerecord.ast.yml b/config/locales/activerecord.ast.yml
new file mode 100644
index 0000000000000000000000000000000000000000..de95817c1fb9c1e83a059f38e355d5ada5bba2dc
--- /dev/null
+++ b/config/locales/activerecord.ast.yml
@@ -0,0 +1,9 @@
+---
+ast:
+  activerecord:
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: namái lletres, númberos y guiones baxos
diff --git a/config/locales/activerecord.cs.yml b/config/locales/activerecord.cs.yml
index 006d3e6005beeffa15bb6b6f870f8c2d9fcebd74..838dee15f89339d1c1b2dd11b644c08758717a9f 100644
--- a/config/locales/activerecord.cs.yml
+++ b/config/locales/activerecord.cs.yml
@@ -10,4 +10,4 @@ cs:
         status:
           attributes:
             reblog:
-              taken: stavu již existuje
+              taken: příspěvku již existuje
diff --git a/config/locales/activerecord.cy.yml b/config/locales/activerecord.cy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..26553012472a326d374bbb34085d653f1f8c41f6
--- /dev/null
+++ b/config/locales/activerecord.cy.yml
@@ -0,0 +1,13 @@
+---
+cy:
+  activerecord:
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: dim ond llythrennau, rhifau a tanlinellau
+        status:
+          attributes:
+            reblog:
+              taken: o'r statws yn bodoli'n barod
diff --git a/config/locales/activerecord.ka.yml b/config/locales/activerecord.ka.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cdd4f9c4c68826f9f0a5e10c6bd76e01e74a4290
--- /dev/null
+++ b/config/locales/activerecord.ka.yml
@@ -0,0 +1,13 @@
+---
+ka:
+  activerecord:
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: მხოლოდ ასოები, ციფრები და "ქვედა-ტირე"
+        status:
+          attributes:
+            reblog:
+              taken: სტატუსის უკვე არსებობს
diff --git a/config/locales/activerecord.ru.yml b/config/locales/activerecord.ru.yml
index 1a7ac997841e6b0f34c13213537f72f345b40cd9..2a2d62a7ef57e04954a3b42a64a847bbf65d6984 100644
--- a/config/locales/activerecord.ru.yml
+++ b/config/locales/activerecord.ru.yml
@@ -6,7 +6,7 @@ ru:
         account:
           attributes:
             username:
-              invalid: только буквы, цифры и символ подеркивания
+              invalid: только буквы, цифры и символ подчёркивания
         status:
           attributes:
             reblog:
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index df47ad290aa256c47aa90faa65ff0c7b5d0f8cfa..9d31e48407d7feb24efd29368db8c76f6323e26f 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -1,25 +1,25 @@
 ---
 ar:
   about:
-    about_hashtag_html: هذه هي الرسائل العامة مع الكلمات الدلالية  <strong> 1#%{hashtag}</strong>. يمكنك التفاعل معهم إذا كان لديك حساب في أي مكان على الإنترنت المتحد.
-    about_mastodon_html: ماستدون شبكة إجتماعية <em>حرة و مفتوحة المصدر</em>. هو بديل <em>لامركزي</em> لمنصات تجارية ، يمكنك من تجنب احتكار شركة واحدة للإتصالات الخاصة بك. يمكنك اختيار أي خادم تثق فيه. أيهما تختار، يمكنك التفاعل مع أي شخص آخر على الشبكة. يمكن لأي شخص تنصيب و تشغيل خادم ماستدون خاص به والمشاركة في <em>الشبكات الاجتماعية</em> بكل شفافية.
+    about_hashtag_html: هذه تبويقات متاحة للجمهور تحتوي على الكلمات الدلالية <strong>#%{hashtag}</strong>. يمكنك التفاعل معها إن كان لديك حساب في أي مكان على الفديفرس.
+    about_mastodon_html: ماستدون شبكة إجتماعية مبنية على أسُس بروتوكولات برمجيات الويب الحرة و مفتوحة المصدر. و هو لامركزي تمامًا كالبريد الإلكتروني.
     about_this: عن مثيل الخادوم هذا
-    administered_by: 'يديره :'
-    closed_registrations: التسجيلات في مثيل الخادوم هذا مُغلقة حاليًا.
+    administered_by: 'يُديره :'
+    api: واجهة برمجة التطبيقات
+    apps: تطبيقات الأجهزة المحمولة
+    closed_registrations: التسجيلات في مثيل الخادوم هذا مُغلقة حاليًا. غير أنه بامكانك العثور على خادم آخر لإنشاء حسابك و مِن ثم النفاذ إلى نفس الشبكة مِن هناك.
     contact: للتواصل معنا
-    contact_missing: غير محدد
+    contact_missing: لم يتم تعيينه
     contact_unavailable: غير متوفر
-    description_headline: ما هو %{domain}?
-    domain_count_after: خوادم أخرى
-    domain_count_before: متصل بـ
+    documentation: الدليل
     extended_description_html: |
       <h3>مكان جيد للقواعد</h3>
-      <p>لا يوجد تفصيل طويل حتى الآن.</p>
+      <p>لم يتم بعد إدخال الوصف الطويل.</p>
     features:
       humane_approach_body: تعلُّمًا مِن فشل الشبكات الأخرى، غاية ماستدون هي بلوغ الخيارات الأخلاقية في التصميم لمُحارَبة إسائة إستعمال شبكات التواصل الإجتماعية.
-      humane_approach_title: أسلوب يعيد الإعتبار للإنسان
+      humane_approach_title: أسلوب يُعيد الإعتبار للفَرد
       not_a_product_body: ماستدون ليس شبكة تجارية. لا يحتوي على إعلانات و لا يقوم باستغلال البيانات و لا هو بِبُستان مُسيَّج. لا تحكم فيه وليس له أية هيئةٍ مركزيةٍ.
-      not_a_product_title: إنك إنسان و لست سلعة
+      not_a_product_title: إنك فرد و لست سلعة
       real_conversation_body: يُمكنكم التعبير عن آرائكم بكل حرية بفضل 65535 حرف و انتقاء دقيق للمحتوى و الوسائط بفضل أدوات التحذير التي هي بين أيديكم.
       real_conversation_title: مبني لتحقيق تواصل حقيقي
       within_reach_body: إبقوا على اتصال دائم بأصدقائكم حيثما كانوا عبر عدة تطبيقات لنظام آي أواس و أندرويد و عدة منصات أخرى بفضل واجهة برمجية للتطبيقات و بيئة صديقة للتطوير.
@@ -28,25 +28,57 @@ ar:
     hosted_on: ماستدون مُستضاف على %{domain}
     learn_more: تعلم المزيد
     other_instances: خوادم أخرى
+    privacy_policy: سياسة الخصوصية
     source_code: الشفرة المصدرية
-    status_count_after: منشورا
+    status_count_after:
+      few: منشورات
+      many: منشورات
+      one: منشور
+      other: منشورات
+      two: منشورات
+      zero: منشورات
     status_count_before: نشروا
-    user_count_after: مستخدم
+    terms: شروط الخدمة
+    user_count_after:
+      few: مستخدمين
+      many: مستخدمين
+      one: مستخدم
+      other: مستخدمين
+      two: مستخدمين
+      zero: مستخدمين
     user_count_before: يستضيف
     what_is_mastodon: ما هو ماستدون ؟
   accounts:
+    choices_html: 'توصيات %{name} :'
     follow: إتبع
-    followers: متابِعون
-    following: يتابعون
+    followers:
+      few: متابِعون
+      many: متابِعون
+      one: متابِع
+      other: متابِعون
+      two: متابِعون
+      zero: متابِعون
+    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: منشورات
+    pin_errors:
+      following: يجب أن تكون مِن متابعي حساب الشخص الذي تريد إبرازه
+    posts:
+      few: تبويقات
+      many: تبويقات
+      one: تبويق
+      other: تبويقات
+      two: تبويقات
+      zero: تبويقات
+    posts_tab_heading: تبويقات
     posts_with_replies: التبويقات و الردود
-    remote_follow: إتبع عن بعد
     reserved_username: إسم المستخدم محجوز
     roles:
       admin: المدير
@@ -54,6 +86,9 @@ ar:
       moderator: مُشرِف
     unfollow: إلغاء المتابعة
   admin:
+    account_actions:
+      action: تنفيذ الاجراء
+      title: اتخاذ إجراء إشراف على %{acct}
     account_moderation_notes:
       create: إترك ملاحظة
       created_msg: تم إنشاء ملاحظة الإشراف بنجاح !
@@ -73,9 +108,10 @@ ar:
       confirm: تأكيد
       confirmed: مؤكَّد
       confirming: التأكد
+      deleted: تمت إزالته
       demote: إنزال الرُتبة الوظيفية
       disable: تعطيل
-      disable_two_factor_authentication: تعطيل 2FA
+      disable_two_factor_authentication: تعطيل المصادقة بخطوتين
       disabled: معطَّل
       display_name: عرض الإسم
       domain: النطاق
@@ -88,8 +124,11 @@ ar:
       followers: المتابِعون
       followers_url: عنوان رابط المتابِعين
       follows: يتابع
+      header: الرأسية
       inbox_url: رابط صندوق الوارد
+      invited_by: تمت دعوته مِن طرف
       ip: عنوان الإيبي
+      joined: انضم
       location:
         all: الكل
         local: المحلي
@@ -97,8 +136,9 @@ ar:
         title: الموقع
       login_status: وضع الدخول
       media_attachments: الوسائط المرفقة
-      memorialize: تحول إلى صفحة للذاكرة
+      memorialize: تحويل الحساب إلى صفحة ذكرى
       moderation:
+        active: نشِط
         all: الكل
         silenced: تم كتمه
         suspended: مُجَمَّد
@@ -106,28 +146,26 @@ ar:
       moderation_notes: ملاحظات الإشراف
       most_recent_activity: آخر نشاط حديث
       most_recent_ip: أحدث عنوان إيبي
+      no_limits_imposed: مِن دون حدود مشروطة
       not_subscribed: غير مشترك
-      order:
-        alphabetic: أبجديًا
-        most_recent: الأحدث
-        title: الترتيب
       outbox_url: رابط صندوق الصادر
-      perform_full_suspension: تعطيل الحساب بالكامل
+      perform_full_suspension: تعليق الحساب
       profile_url: رابط الملف الشخصي
       promote: ترقية
       protocol: البروتوكول
       public: عمومي
       push_subscription_expires: انتهاء الاشتراك ”PuSH“
-      redownload: تحديث الصورة الرمزية
+      redownload: تحديث الصفحة الشخصية
       remove_avatar: حذف الصورة الرمزية
+      remove_header: حذف الرأسية
       resend_confirmation:
         already_confirmed: هذا المستخدم مؤكد بالفعل
         send: أعد إرسال رسالة البريد الالكتروني الخاصة بالتأكيد
         success: تم إرسال رسالة التأكيد بنجاح!
       reset: إعادة التعيين
       reset_password: إعادة ضبط كلمة السر
-      resubscribe: اشترك مرة أخرى
-      role: التصريحات
+      resubscribe: إعادة الإشتراك
+      role: الصلاحيات
       roles:
         admin: مدير
         moderator: مشرف
@@ -138,27 +176,30 @@ ar:
       shared_inbox_url: رابط الصندوق المُشترَك للبريد الوارد
       show:
         created_reports: البلاغات التي أنشأها هذا الحساب
-        report: التقرير
-        targeted_reports: التقريرات التي أُنشِأت ضد هذا الحساب
-      silence: سكتهم
+        targeted_reports: الشكاوي التي أُنشِأت مِن طرف الآخَرين
+      silence: كتم
+      silenced: تم كتمه
       statuses: المنشورات
       subscribe: اشترك
+      suspended: تم تعليقه
       title: الحسابات
-      unconfirmed_email: البريد الإلكتروني غير المؤكد
+      unconfirmed_email: البريد الإلكتروني غير مؤكد
       undo_silenced: رفع الصمت
       undo_suspension: إلغاء تعليق الحساب
       unsubscribe: إلغاء الاشتراك
       username: إسم المستخدم
+      warn: تحذير
       web: الويب
     action_logs:
       actions:
-        assigned_to_self_report: قام {name} بتعيين التقرير٪ {target} لأنفسهم
-        change_email_user: غيّر٪ {name} عنوان البريد الإلكتروني للمستخدم٪ {target}
+        assigned_to_self_report: قام %{name} بتعيين التقرير %{target} لأنفسهم
+        change_email_user: غيّر %{name} عنوان البريد الإلكتروني للمستخدم %{target}
         confirm_user: "%{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}
@@ -169,17 +210,18 @@ ar:
         enable_user: لقد قام %{name} بتنشيط تسجيل الدخول للمستخدِم %{target}
         memorialize_account: لقد قام %{name} بتحويل حساب %{target} إلى صفحة تذكارية
         promote_user: "%{name} قام بترقية المستخدم %{target}"
-        remove_avatar_user: تمت إزالة٪ {name} الصورة الرمزية٪ {target}
-        reopen_report: تمت إعادة فتح التقرير {name}٪ {target}
+        remove_avatar_user: تمت إزالة %{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}"
         update_status: لقد قام %{name} بتحديث منشور %{target}
+      deleted_status: "(منشور محذوف)"
       title: سِجلّ التفتيش و المعاينة
     custom_emojis:
       by_domain: النطاق
@@ -206,8 +248,30 @@ ar:
       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: إضافة نطاق جديد
+      add_new: إضافة حجب جديد لنطاق
       created_msg: إنّ حجب النطاق حيز التشغيل
       destroyed_msg: تم إلغاء الحجب المفروض على النطاق
       domain: النطاق
@@ -222,22 +286,24 @@ ar:
         title: حجب نطاق جديد
       reject_media: رفض ملفات الوسائط
       reject_media_hint: يزيل ملفات الوسائط المخزنة محليًا ويرفض تنزيل أي ملفات في المستقبل. غير ذي صلة للتعليق
-      severities:
-        noop: لا شيء
-        silence: إخفاء أو كتم
-        suspend: تعليق
-      severity: الشدة
+      reject_reports: رفض التقارير
+      severity:
+        silence: تم كتمه
+        suspend: تم تعليقه
       show:
         affected_accounts:
-          one: هناك حساب واحد متأثر في قاعدة البيانات
-          other: هناك %{count} حسابات في قاعدة البيانات متأثرة بذلك
+          few: "%{count} حسابات معنية في قاعدة البيانات"
+          many: "%{count} حسابات معنية في قاعدة البيانات"
+          one: حساب واحد معني في قاعدة البيانات
+          other: "%{count} حسابات معنية في قاعدة البيانات"
+          two: حسابات معنية في قاعدة البيانات
+          zero: حسابات معنية في قاعدة البيانات
         retroactive:
           silence: إلغاء الكتم عن كافة الحسابات المتواجدة على هذا النطاق
           suspend: إلغاء التعليق المفروض على كافة حسابات هذا النطاق
         title: رفع حظر النطاق عن %{domain}
         undo: إلغاء
-      title: حظر النطاقات
-      undo: إلغاء
+      undo: إلغاء حجب النطاق
     email_domain_blocks:
       add_new: إضافة
       created_msg: لقد دخل حظر نطاق البريد الإلكتروني حيّز الخدمة
@@ -248,24 +314,51 @@ ar:
         create: إضافة نطاق
         title: إضافة نطاق بريد جديد إلى اللائحة السوداء
       title: القائمة السوداء للبريد الإلكتروني
+    followers:
+      back_to_account: العودة إلى الحساب
+      title: "%{acct} مُتابِعون"
     instances:
-      account_count: الحسابات المعروفة
-      domain_name: النطاق
-      reset: إعادة تعيين
-      search: البحث
-      title: مثيلات الخوادم المعروفة
+      known_accounts:
+        few: "%{count} حسابات معروفة"
+        many: "%{count} حسابات معروفة"
+        one: حساب معروف %{count}
+        other: "%{count} حسابات معروفة"
+        two: "%{count} حسابات معروفة"
+        zero: "%{count} حسابات معروفة"
+      moderation:
+        all: كافتها
+        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: حذف
+      disable: تعطيل
+      disabled: مُعطَّل
+      enable: تشغيل
+      enable_hint: عندما تقوم بتنشيط هذه الميزة، سوف يشترك خادومك في جميع التبويقات القادمة مِن هذا المُرحِّل و سيشرع كذلك بإرسال كافة التبويقات العمومية إليه.
+      enabled: مُشغَّل
+      inbox_url: رابط المُرحّل
+      pending: في انتظار تسريح المُرحِّل
+      save_and_enable: حفظ وتشغيل
+      setup: إعداد اتصال بمُرحّل
+      status: الحالة
+      title: المُرحّلات
     report_notes:
-      created_msg: |-
-        41/5000
-        تم إنشاء ملاحظة التقرير بنجاح!
-      destroyed_msg: تم حذف ملاحظة التقرير بنجاح!
+      created_msg: تم إنشاء ملاحظة الشكوى بنجاح!
+      destroyed_msg: تم حذف ملاحظة الشكوى بنجاح!
     reports:
       account:
         note: ملحوظة
@@ -277,8 +370,7 @@ ar:
       comment:
         none: لا شيء
       created_at: ذكرت
-      id: معرّف ID
-      mark_as_resolved: إعتبار التقرير كمحلول
+      mark_as_resolved: إعتبار الشكوى كمحلولة
       mark_as_unresolved: علام كغير محلولة
       notes:
         create: اضف ملاحظة
@@ -286,22 +378,17 @@ ar:
         create_and_unresolve: إعادة فتح مع ملاحظة
         delete: حذف
         placeholder: قم بوصف الإجراءات التي تم اتخاذها أو أي تحديثات أخرى ذات علاقة …
-      reopen: إعادة فتح التقرير
-      report: 'التقرير #%{id}'
-      report_contents: المحتويات
+      reopen: إعادة فتح الشكوى
+      report: 'الشكوى #%{id}'
       reported_account: حساب مُبلّغ عنه
       reported_by: أبلغ عنه من طرف
       resolved: معالجة
       resolved_msg: تم حل تقرير بنجاح!
-      silence_account: كتم و إخفاء الحساب
       status: الحالة
-      suspend_account: فرض تعليق على الحساب
-      target: الهدف
-      title: التقارير
+      title: الشكاوي
       unassign: إلغاء تعيين
       unresolved: غير معالجة
       updated_at: محدث
-      view: عرض
     settings:
       activity_api_enabled:
         desc_html: عدد المنشورات المحلية و المستخدمين النشطين و التسجيلات الأسبوعية الجديدة
@@ -312,12 +399,21 @@ ar:
       contact_information:
         email: البريد الإلكتروني المهني
         username: الإتصال بالمستخدِم
+      custom_css:
+        desc_html: يقوم بتغيير المظهر بواسطة سي أس أس يُحمَّل على كافة الصفحات
+        title: سي أس أس مخصص
       hero:
         desc_html: معروض على الصفحة الأولى. لا يقل عن 600 × 100 بكسل. عند عدم التعيين ، تعود الصورة إلى النسخة المصغرة على سبيل المثال
         title: الصورة الرأسية
       peers_api_enabled:
         desc_html: أسماء النطاقات التي إلتقى بها مثيل الخادوم على البيئة الموحَّدة فيديفرس
         title: نشر عدد مثيلات الخوادم التي تم مصادفتها
+      preview_sensitive_media:
+        desc_html: روابط المُعَاينة على مواقع الويب الأخرى ستقوم بعرض صُوَر مصغّرة حتى و إن كانت الوسائط حساسة
+        title: إظهار الصور الحساسة في مُعاينات أوبن غراف
+      profile_directory:
+        desc_html: السماح للمستخدمين الكشف عن حساباتهم
+        title: تفعيل سجل الملفات الشخصية
       registrations:
         closed_message:
           desc_html: يتم عرضه على الصفحة الرئيسية عندما يتم غلق تسجيل الحسابات الجديدة. يمكنكم إستخدام علامات الأيتش تي أم أل HTML
@@ -338,11 +434,14 @@ ar:
         desc_html: عرض شارة الموظفين على صفحة المستخدم
         title: إظهار شارة الموظفين
       site_description:
-        desc_html: فقرة تمهيدية على الصفحة الأولى وفي العلامات الوصفية. يمكنك استخدام علامات HTML ، ولا سيما <code>&lt;a&gt;</code> و <code>&lt;em&gt;</code>.
+        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: مقدمة وصفية قصيرة عن مثيل الخادوم
       site_terms:
         desc_html: يمكنك كتابة سياسة الخصوصية الخاصة بك ، شروط الخدمة أو غيرها من القوانين. يمكنك استخدام علامات HTML
         title: شروط الخدمة المخصصة
@@ -358,14 +457,15 @@ ar:
       back_to_account: العودة إلى صفحة الحساب
       batch:
         delete: حذف
-        nsfw_off: ضع علامة انها غير حساسة
-        nsfw_on: ضع علامة انها حساسة
+        nsfw_off: تعيينه كمنشور غير حساس
+        nsfw_on: تعيينه كمنشور حساس
       failed_to_execute: خطأ في التفعيل
       media:
         title: الوسائط
-      no_media: لا يوجد وسائط
+      no_media: لا تحتوي على وسائط
+      no_status_selected: لم يطرأ أي تغيير على أي منشور بما أنه لم يتم اختيار أي واحد
       title: منشورات الحساب
-      with_media: بالوسائط
+      with_media: تحتوي على وسائط
     subscriptions:
       callback_url: عاود الاتصال بالعنوان
       confirmed: مؤكَّد
@@ -373,11 +473,25 @@ ar:
       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_report:
       body: قام %{reporter} بالإبلاغ عن %{target}
-      body_remote: أبلغ شخص ما من٪ {domain} عن٪ {target}
+      body_remote: أبلغ شخص ما من %{domain} عن %{target}
       subject: تقرير جديد ل%{instance} (#%{id})
   application_mailer:
     notification_preferences: تعديل خيارات البريد الإلكتروني
@@ -395,7 +509,7 @@ ar:
     warning: كن حذرا مع هذه البيانات. لا تقم أبدا بمشاركتها مع الآخَرين !
     your_token: رمز نفاذك
   auth:
-    agreement_html: بقبولك التسجيل فإنك تُصرِّح قبول <a href="%{rules_path}">قواعد مثيل الخادوم</a> و <a href="%{terms_path}">شروط الخدمة التي نوفرها لك</a>.
+    agreement_html: بمجرد النقر على "التسجيل" أسفله، فإنك تُصرِّح قبول <a href="%{rules_path}">قواعد مثيل الخادوم</a> و <a href="%{terms_path}">شروط الخدمة التي نوفرها لك</a>.
     change_password: الكلمة السرية
     confirm_email: تأكيد عنوان البريد الإلكتروني
     delete_account: حذف حساب
@@ -449,6 +563,18 @@ ar:
     proceed: حذف حساب
     success_msg: تم حذف حسابك بنجاح
     warning_title: توافر المحتوى المنشور و المبعثَر
+  directories:
+    directory: سِجلّ الحسابات
+    enabled: إنّ حسابك الآن ضمن فهرس المستخدِمين.
+    explanation: استكشف مستخدِمين آخرين حسب المواضيع التي تهمهم
+    explore_mastodon: استكشف %{title}
+    people:
+      few: "%{count} شخص"
+      many: "%{count} شخص"
+      one: "%{count} شخص"
+      other: "%{count} شخص"
+      two: "%{count} شخص"
+      zero: "%{count} شخص"
   errors:
     '403': ليس لك الصلاحيات الكافية لعرض هذه الصفحة.
     '404': إنّ الصفحة التي تبحث عنها لا وجود لها أصلا.
@@ -460,7 +586,7 @@ ar:
     '500':
       content: نحن متأسفون، لقد حدث خطأ ما مِن جانبنا.
       title: هذه الصفحة خاطئة
-    noscript_html: يرجى تفعيل الجافا سكريبت لاستخدام تطبيق الويب لماستدون، أو عِوض ذلك قوموا بتجريب إحدى <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">التطبيقات الأصلية</a> الدّاعمة لماستدون على منصّتكم.
+    noscript_html: يرجى تفعيل الجافا سكريبت لاستخدام تطبيق الويب لماستدون، أو عِوض ذلك قوموا بتجريب إحدى <a href="%{apps_path}">التطبيقات الأصلية</a> الدّاعمة لماستدون على منصّتكم.
   exports:
     archive_takeout:
       date: التاريخ
@@ -472,6 +598,7 @@ ar:
     blocks: قمت بحظر
     csv: CSV
     follows: أنت تتبع
+    lists: القوائم
     mutes: قُمتَ بكتم
     storage: ذاكرة التخزين
   filters:
@@ -482,6 +609,9 @@ ar:
       thread: المحادثات
     edit:
       title: تعديل عامل التصفية
+    errors:
+      invalid_context: لم تقم بتحديد أي مجال أو أنّ المجال غير صالح
+      invalid_irreversible: إلّا مجالات الإشعارات و الخيط الرئيسي معنية بالتصفية اللارجعية
     index:
       delete: إزالة
       title: عوامل التصفية
@@ -492,25 +622,34 @@ ar:
     followers_count: عدد المتابِعين
     lock_link: قم بتجميد حسابك
     purge: تنحية من بين متابعيك
-    success:
-      one: جارية عملية حظر المتابِعين بسلاسة من نطاق آخر ...
-      other: جارية عملية حظر المتابِعين بسلاسة من %{count} نطاقات أخرى ...
+    success: جارية عملية حظر المتابِعين بسلاسة من %{count} نطاقات أخرى ...
+    true_privacy_html: تذكر دائمًا أنّ <strong>الخصوصية التامة لا يمكن بلوغها إلّا بالتعمية و التشفير من طرف إلى آخَر</strong>.
+    unlocked_warning_html: يمكن لأي كان متابعة حسابك و الإطلاع مباشرة على تبويقاتك. إستخدِم %{lock_link} لمُعاينة أو رفض طلبات المتابِعين الجُدُد.
     unlocked_warning_title: إنّ حسابك غير مقفل
+  footer:
+    developers: المطورون
+    more: المزيد …
+    resources: الموارد
   generic:
     changes_saved_msg: تم حفظ التعديلات بنجاح !
-    powered_by: مدعوم بـ %{link}
+    copy: نسخ
     save_changes: حفظ التغييرات
     validation_errors:
-      one: لا يزال هناك خلل ما إلى حد الآن. يُرجى إعادة النظر في الخطأ أسفله
-      other: هناك شيء ليس على ما يرام ! رجاءًا تحقق من الأخطاء الـ %{count} أسفله
+      few: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
+      many: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
+      one: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الخطأ أدناه
+      other: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
+      two: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
+      zero: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
   imports:
-    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.
+    preface: بإمكانك استيراد بيانات قد قُمتَ بتصديرها مِن مثيل خادوم آخَر، كقوائم المستخدِمين الذين كنتَ تتابِعهم أو قُمتَ بحظرهم.
     success: تم تحميل بياناتك بنجاح وسيتم معالجتها في الوقت المناسب
     types:
       blocking: قائمة المحظورين
       following: قائمة المستخدمين المتبوعين
       muting: قائمة الكتم
     upload: تحميل
+  in_memoriam_html: في ذكرى.
   invites:
     delete: تعطيل
     expired: إنتهت صلاحيتها
@@ -525,16 +664,18 @@ ar:
     generate: توليد
     invited_by: 'تمت دعوتك من طرف :'
     max_uses:
-      one: إستعمال واحد
+      few: "%{count} استخدامات"
+      many: "%{count} استخدامات"
+      one: استخدام واحد
       other: "%{count} استخدامات"
+      two: استخدامات
+      zero: استخدامات
     max_uses_prompt: بلا حدود
     prompt: توليد و مشاركة روابط للسماح للآخَرين بالنفاذ إلى مثيل الخادوم هذا
     table:
       expires_at: تنتهي مدة صلاحيتها في
-      uses: يستخدِم
+      uses: عدد الاستخدامات
     title: دعوة أشخاص
-  landing_strip_html: "<strong>%{name}</strong> هو أحد مُستخدِمي %{link_to_root_path}. بإمكانك متابعته أو التواصل معه إن كنت تملك حسابًا أيا كان على البيئة الموحَّدة فيديفرس."
-  landing_strip_signup_html: إن كنت لا تملك واحدا، يمكنك <a href="%{sign_up_path}">التسجيل مِن هنا</a>.
   lists:
     errors:
       limit: لقد بلغت الحد الأقصى للقوائم
@@ -555,11 +696,19 @@ ar:
       body: هذا هو مُلَخَّص الرسائل التي فاتتك وذلك منذ آخر زيارة لك في  %{since}
       mention: "%{name} أشار إليك في :"
       new_followers_summary:
-        one: و لقد حصلت على متابع جديد أثناء فترة غيابك ! مرحى !
-        other: و لقد تحصلت على %{count} متتبعين جدد أثناء فترة غيابك ! رائع !
+        few: رائع، لقد قام بمتابَعتك %{count} مُتابِعون جُدد أثناء فترة غيابك عن ماستدون!
+        many: رائع، لقد قام بمتابَعتك %{count} مُتابِعون جُدد أثناء فترة غيابك عن ماستدون!
+        one: و لقد تحصّلتَ كذلك على مُتابِع آخَر بينما كنتَ غائبًا! هذا شيء رائع!
+        other: رائع، لقد قام بمتابَعتك %{count} مُتابِعون جُدد أثناء فترة غيابك عن ماستدون!
+        two: رائع، لقد قام بمتابَعتك %{count} مُتابِعون جُدد أثناء فترة غيابك عن ماستدون!
+        zero: رائع، لقد قام بمتابَعتك %{count} مُتابِعون جُدد أثناء فترة غيابك عن ماستدون!
       subject:
-        one: "إشعار واحد منذ زيارتك الأخيرة \U0001F418"
-        other: "%{count} إشعارات جديدة منذ زيارتك الأخيرة \U0001F418"
+        few: "%{count} إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
+        many: "%{count} إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
+        one: "إشعار واحد 1 منذ آخر زيارة لك لـ \U0001F418"
+        other: "%{count} إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
+        two: "إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
+        zero: "إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
       title: أثناء فترة غيابك …
     favourite:
       body: 'أُعجب %{name} بمنشورك :'
@@ -590,8 +739,8 @@ ar:
         units:
           billion: B
           million: M
-          quadrillion: Q
-          thousand: K
+          quadrillion: كواد
+          thousand: ألف
           trillion: T
           unit: ''
   pagination:
@@ -606,7 +755,7 @@ ar:
     publishing: النشر
     web: الويب
   remote_follow:
-    acct: قم بإدخال عنوان حسابك username@domain الذي من خلاله تود المتابعة
+    acct: قم بإدخال عنوان حسابك username@domain الذي من خلاله تود النشاط
     missing_resource: تعذر العثور على رابط التحويل المطلوب الخاص بحسابك
     no_account_html: أليس عندك حساب بعدُ ؟ يُمْكنك <a href='%{sign_up_path}' target='_blank'>التسجيل مِن هنا</a>
     proceed: أكمل المتابعة
@@ -675,24 +824,38 @@ ar:
     attached:
       description: 'مُرفَق : %{attached}'
       image:
-        one: "%{count} صورة"
+        few: "%{count} صور"
+        many: "%{count} صور"
+        one: صورة %{count}
         other: "%{count} صور"
+        two: صور
+        zero: صور
       video:
-        one: "%{count} فيديو"
+        few: "%{count} فيديوهات"
+        many: "%{count} فيديوهات"
+        one: فيديو %{count}
         other: "%{count} فيديوهات"
+        two: فيديوهات
+        zero: فيديوهات
+    boosted_from_html: تم إعادة ترقيته مِن %{acct_link}
     content_warning: 'تحذير عن المحتوى : %{warning}'
     disallowed_hashtags:
-      one: 'يحتوي على وسم ممنوع : %{tags}'
-      other: 'يحتوي على وسوم ممنوعة : %{tags}'
+      few: 'يحتوي على وسوم غير مسموح بها: %{tags}'
+      many: 'يحتوي على وسوم غير مسموح بها: %{tags}'
+      one: 'يحتوي على وسم غير مسموح به: %{tags}'
+      other: 'يحتوي على وسوم غير مسموح بها: %{tags}'
+      two: 'يحتوي على وسوم غير مسموح بها: %{tags}'
+      zero: 'يحتوي على وسوم غير مسموح بها: %{tags}'
     language_detection: اكتشاف اللغة تلقائيا
     open_in_web: إفتح في الويب
     over_character_limit: تم تجاوز حد الـ %{max} حرف المسموح بها
     pin_errors:
       limit: لقد بلغت الحد الأقصى للتبويقات المدبسة
       ownership: لا يمكن تدبيس تبويق نشره شخص آخر
-      private: لا يمكن تثبيت تبويق لم يُنشر للعامة
+      private: لا يمكن تدبيس تبويق لم يُنشر للعامة
       reblog: لا يمكن تثبيت ترقية
     show_more: أظهر المزيد
+    sign_in_to_participate: قم بتسجيل الدخول للمشاركة في هذه المحادثة
     title: '%{name} : "%{quote}"'
     visibilities:
       private: إعرض فقط لمتتبعيك
@@ -702,9 +865,8 @@ ar:
       unlisted: غير مُدرَج
       unlisted_long: يُمكن لأيٍ كان رُؤيتَه و لكن لن يُعرَض على الخيوط العامة
   stream_entries:
-    click_to_show: إضغط للعرض
     pinned: تبويق مثبّت
-    reblogged: رقى
+    reblogged: رقّاه
     sensitive_content: محتوى حساس
   terms:
     title: شروط الخدمة وسياسة الخصوصية على %{instance}
@@ -715,6 +877,7 @@ ar:
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: قم بإدخال الرمز المُوَلّد عبر تطبيق المصادقة للتأكيد
     description_html: في حال تفعيل <strong>المصادقة بخطوتين </strong>، فتسجيل الدخول يتطلب منك أن يكون بحوزتك هاتفك النقال قصد توليد الرمز الذي سيتم إدخاله.
@@ -724,6 +887,7 @@ ar:
     enabled_success: تم تفعيل المصادقة بخطوتين بنجاح
     generate_recovery_codes: توليد رموز الإسترجاع
     instructions_html: "<strong>قم بمسح رمز الكيو آر عبر Google Authenticator أو أي تطبيق TOTP على جهازك</strong>. من الآن فصاعدا سوف يقوم ذاك التطبيق بتوليد رموز يجب عليك إدخالها عند تسجيل الدخول."
+    lost_recovery_codes: تُمكّنك رموز الإسترجاع الإحتاطية مِن استرجاع النفاذ إلى حسابك في حالة فقدان جهازك المحمول. إن ضاعت منك هذه الرموز فبإمكانك إعادة توليدها مِن هنا و إبطال الرموز القديمة.
     manual_instructions: 'في حالة تعذّر مسح رمز الكيو آر أو طُلب منك إدخال يدوي، يُمْكِنك إدخال هذا النص السري على التطبيق :'
     recovery_codes: النسخ الإحتياطي لرموز الإسترجاع
     recovery_codes_regenerated: تم إعادة توليد رموز الإسترجاع الإحتياطية بنجاح
@@ -731,21 +895,40 @@ ar:
     wrong_code: الرمز الذي أدخلته غير صالح ! تحقق من صحة الوقت على الخادم و الجهاز ؟
   user_mailer:
     backup_ready:
-      explanation: ''
+      explanation: لقد قمت بطلب نسخة كاملة لحسابك على ماستدون. إنها متوفرة الآن للتنزيل !
       subject: نسخة بيانات حسابك جاهزة للتنزيل
       title: المغادرة بأرشيف الحساب
+    warning:
+      review_server_policies: مراجعة شروط السيرفر
+      subject:
+        disable: تم تجميد حسابك %{acct}
+      title:
+        disable: الحساب مُجمَّد
+        none: تحذير
+        suspend: الحساب مُعلَّق
     welcome:
       edit_profile_action: تهيئة الملف الشخصي
+      edit_profile_step: يُمكنك·كي تخصيص ملفك الشخصي عن طريق تحميل صورة رمزية ورأسية و بتعديل  إسمك·كي العلني وأكثر. و إن أردت·تي معاينة المتابِعين و المتابعات الجُدد قبيل السماح لهم·ن بمتابَعتك فيمكنك·كي تأمين حسابك·كي.
       explanation: ها هي بعض النصائح قبل بداية الإستخدام
       final_action: اشرَع في النشر
+      final_step: |-
+        يمكنك الشروع في النشر في الحين ! حتى و إن لم كنت لا تمتلك متابِعين بعدُ، يمكن للآخرين الإطلاع على منشوراتك الموجهة للجمهور على الخيط المحلي أو إن قمت باستخدام وسوم.
+        إبدأ بتقديم نفسك باستعمال وسم #introductions.
       full_handle: عنوانك الكامل
+      full_handle_hint: هذا هو ما يجب تقديمه لأصدقائك قصد أن يكون بإمكانهم متابَعتك أو مُراسَلتك حتى و إن كانت حساباتهم على خوادم أخرى.
       review_preferences_action: تعديل التفضيلات
       subject: أهلًا بك على ماستدون
+      tip_federated_timeline: الخيط الزمني الفديرالي هو بمثابة شبه نظرة شاملة على شبكة ماستدون. غير أنه لا يشمل إلا على الأشخاص المتابَعين مِن طرف جيرانك و جاراتك، لذا فهذا الخيط لا يعكس كافة الشبكة برُمّتها.
+      tip_following: أنت تتبع تلقائيا مديري و مديرات الخادم. للعثور على أشخاص مميزين أو قد تهمك حساباتهم بإمكانك الإطلاع على الخيوط المحلية و كذا الفدرالية.
+      tip_local_timeline: الخيط الزمني المحلي هو بمثابة نظرة سريعة على الأشخاص المتواجدين على %{instance} يمكن اعتبارهم كجيرانك وجاراتك الأقرب إليك!
       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:
+    verification: التحقق
diff --git a/config/locales/ast.yml b/config/locales/ast.yml
new file mode 100644
index 0000000000000000000000000000000000000000..78ad796a00de762fb3d46587924d5d852e875a83
--- /dev/null
+++ b/config/locales/ast.yml
@@ -0,0 +1,361 @@
+---
+ast:
+  about:
+    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
+    documentation: Documentación
+    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:
+      one: usuariu
+      other: usuarios
+    user_count_before: Ye'l llar de
+    what_is_mastodon: "¿Qué ye Mastodon?"
+  accounts:
+    followers:
+      one: Xente que te sigue
+      other: Siguidores
+    joined: Xunióse en %{date}
+    moved_html: "%{name} mudóse a %{new_profile_link}:"
+    network_hidden: Esta información nun ta disponible
+    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:
+      bot: Robó
+  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
+      protocol: Protocolu
+      resend_confirmation:
+        already_confirmed: Esti usuariu yá ta confirmáu
+      role: Permisos
+      roles:
+        admin: Alministrador
+        moderator: Llendador
+        user: Usuariu
+      statuses: Estaos
+      title: Cuentes
+      username: Nome d'usuariu
+      web: Web
+    action_logs:
+      actions:
+        create_domain_block: "%{name} bloquió'l dominiu %{target}"
+        disable_custom_emoji: "%{name} desactivó'l fustaxe %{target}"
+        disable_user: "%{name} desactivó l'aniciu de sesión del usuariu %{target}"
+    custom_emojis:
+      by_domain: Dominiu
+      copy_failed_msg: Nun pudo facese una copia llocal d'esi fustaxe
+      emoji: Fustaxe
+      update_failed_msg: Nun pudo anovase esi fustaxe
+    dashboard:
+      config: Configuración
+      feature_registrations: Rexistros
+      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
+    domain_blocks:
+      domain: Dominiu
+    email_domain_blocks:
+      domain: Dominiu
+    instances:
+      title: Instancies conocíes
+    invites:
+      filter:
+        available: Disponible
+        expired: Caducó
+      title: Invitaciones
+    relays:
+      save_and_enable: Guardar y activar
+    reports:
+      are_you_sure: "¿De xuru?"
+      status: Estáu
+    settings:
+      registrations:
+        min_invite_role:
+          disabled: Naide
+      site_description:
+        title: Descipción de la instancia
+      site_title: Nome de la instancia
+      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.
+    forgot_password: "¿Escaeciesti la contraseña?"
+    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
+    error: Desafortunadamente, hebo un fallu guetando la cuenta remota
+    follow_request: 'Unviesti una solicitú de siguimientu a:'
+    post_follow:
+      close: O pues zarrar esta ventana.
+      return: Amosar el perfil del usuariu
+      web: Dir a la web
+  datetime:
+    distance_in_words:
+      half_a_minute: Púramente agora
+      less_than_x_seconds: Púramente agora
+  deletes:
+    bad_password_msg: "¡Bon intentu, crackers! Contraseña incorreuta"
+    confirm_password: Introduz la contraseña pa verificar la to identidá
+  directories:
+    people:
+      one: "%{count} persona"
+      other: "%{count} persones"
+  errors:
+    '403': Nun tienes permisu pa ver esta páxina.
+    '404': La páxina que tabes guetando nun esiste.
+    '410': La páxina que tabes guetando yá nun esiste.
+    '422':
+      content: Falló la verificación de seguranza. ¿Tas bloquiando les cookies?
+      title: Falló la verificación de seguranza
+    '429': Ficiéronse milenta solicitúes
+  exports:
+    archive_takeout:
+      date: Data
+      hint_html: Pues solicitar un archivu colos tos <strong>toots y ficheros xubíos</strong>. Los datos esportaos van tar nel formatu ActivityPub, llexible pa cualesquier software que seya compatible. Pues solicitar un archivu cada 7 díes.
+      request: Solicitar l'archivu
+      size: Tamañu
+    blocks: Xente que bloquiesti
+    csv: CSV
+    follows: Xente que sigues
+    mutes: Xente que silenciesti
+  filters:
+    contexts:
+      notifications: Avisos
+      public: Llinies temporales públiques
+      thread: Conversaciones
+    index:
+      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
+  imports:
+    preface: Pues importar los datos qu'esportares dende otra instancia, como por exemplu la llista de persones que bloquiares o tubieres siguiendo.
+    types:
+      blocking: Llista de xente bloquiao
+      following: Llista de siguidores
+      muting: Llista de xente silenciao
+    upload: Xubir
+  invites:
+    delete: Desactivar
+    expired: Caducó
+    expires_in:
+      '1800': 30 minutos
+      '21600': 6 hores
+      '3600': 1 hora
+      '43200': 12 hores
+      '604800': 1 selmana
+      '86400': 1 día
+    expires_in_prompt: Enxamás
+    invited_by: 'Convidóte:'
+    max_uses:
+      one: 1 usu
+      other: "%{count} usos"
+    table:
+      expires_at: Data de caducidá
+      uses: Usos
+  lists:
+    errors:
+      limit: Algamesti la cantidá máxima de llistes
+  media_attachments:
+    validations:
+      images_and_video: Nun pue axuntase un videu a un estáu que yá contién imáxenes
+      too_many: Nun puen axuntase más de 4 ficheros
+  migrations:
+    acct: nome_usuariu@dominiu de la cuenta nueva
+    proceed: Guardar
+  notification_mailer:
+    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
+    follow_request:
+      body: "%{name} solicitó siguite"
+      title: Petición nueva de siguimientu
+    mention:
+      body: "%{name} mentóte en:"
+      subject: "%{name} mentóte"
+      title: Mención nueva
+    reblog:
+      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>"
+    proceed: Siguir
+    prompt: 'Vas siguir a:'
+  remote_unfollow:
+    error: Fallu
+  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:
+      image:
+        one: "%{count} imaxe"
+        other: "%{count} imáxenes"
+      video:
+        one: "%{count} videu"
+        other: "%{count} vídeos"
+    boosted_from_html: Compartióse'l toot dende %{acct_link}
+    language_detection: Deteutala automáticamente
+    pin_errors:
+      limit: Yá fixesti'l númberu máxiumu de toots
+      ownership: Nun pue fixase'l toot d'otra persona
+      private: Nun puen fixase los toots que nun seyan públicos
+      reblog: Nun pue fixase un toot compartíu
+    show_more: Amosar más
+    title: "%{name}: «%{quote}»"
+    visibilities:
+      private: Namái siguidores
+  stream_entries:
+    reblogged: compartióse
+    sensitive_content: Conteníu sensible
+  themes:
+    default: Mastodon
+  two_factor_authentication:
+    code_hint: Introduz el códigu xeneráu pola aplicación autenticadora pa confirmar
+    disable: Desactivar
+    enabled: L'autenticación en dos pasos ta activada
+    enabled_success: L'autenticación en dos pasos activóse con ésitu
+    generate_recovery_codes: Xenerar códigos de recuperación
+    lost_recovery_codes: Los códigos de recuperación permítente recuperar l'accesu a la cuenta si pierdes el teléfonu. Si tamién pierdes esos códigos, pues xeneralos de nueves equí. Los códigos de recuperación vieyos van invalidase.
+    manual_instructions: 'Si nun pues escaniar el códigu QR y precises introducilu a mano, equí ta''l secretu en testu planu:'
+    recovery_codes: Códigos de recuperación
+    recovery_codes_regenerated: Los códigos de recuperación rexeneráronse con ésitu
+  user_mailer:
+    welcome:
+      full_handle_hint: Esto ye lo que-yos diríes a los collacios pa que puean unviate mensaxes o siguite dende otra instancia.
+      subject: Afáyate en Mastodon
+      tips: Conseyos
+  users:
+    invalid_email: La direición de corréu nun ye válida
+    seamless_external_login: Aniciesti sesión pente un serviciu esternu, polo que los axustes de la contraseña y corréu nun tán disponibles.
+  verification:
+    verification: Verificación
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index cb3ed22449c7447e69ff4a52a5c3f78f66900ac4..4de5b1e22a34866ceb7a2e44094971ed8b4bcaea 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -5,9 +5,6 @@ bg:
     about_this: За тази инстанция
     closed_registrations: В момента регистрациите за тази инстанция са затворени.
     contact: За контакти
-    description_headline: Какво е %{domain}?
-    domain_count_after: други инстанции
-    domain_count_before: Свързани към
     other_instances: Други инстанции
     source_code: Програмен код
     status_count_after: публикации
@@ -22,7 +19,6 @@ bg:
     people_followed_by: Хора, които %{name} следва
     people_who_follow: Хора, които следват %{name}
     posts: Публикации
-    remote_follow: Последвай
     unfollow: Не следвай
   application_mailer:
     settings: 'Промяна на предпочитанията за e-mail: %{link}'
@@ -52,11 +48,11 @@ bg:
       half_a_minute: Току-що
       less_than_x_minutes: "%{count} мин."
       less_than_x_seconds: Току-що
-      over_x_years: "%{count} г."
+      over_x_years: "%{count} г"
       x_days: "%{count} дни"
-      x_minutes: "%{count} мин."
-      x_months: "%{count} м."
-      x_seconds: "%{count} сек."
+      x_minutes: "%{count} мин"
+      x_months: "%{count} м"
+      x_seconds: "%{count} сек"
   exports:
     blocks: Вашите блокирания
     csv: CSV
@@ -64,27 +60,22 @@ bg:
     storage: Съхранение на мултимедия
   generic:
     changes_saved_msg: Успешно запазване на промените!
-    powered_by: поддържано от %{link}
     save_changes: Запази промените
-    validation_errors:
-      one: Нещо все още не е наред! Моля, прегледай грешката по-долу
-      other: Нещо все още не е наред! Моля, прегледай грешките по-долу
+    validation_errors: Нещо все още не е наред! Моля, прегледай грешките по-долу
   imports:
     preface: Можеш да импортираш някои данни, като например всички хора, които следваш или блокираш в акаунта си на тази инстанция, от файлове, създадени чрез експорт в друга инстанция.
-    success: Твоите данни бяха успешно качени и ще бъдат обработени впоследствие.
+    success: Твоите данни бяха успешно качени и ще бъдат обработени впоследствие
     types:
       blocking: Списък на блокираните
       following: Списък на последователите
     upload: Качване
-  landing_strip_html: "<strong>%{name}</strong> е потребител от %{link_to_root_path}. Можеш да ги следваш, или да контактуваш с тях, ако имаш акаунт където и да е из федерираната вселена на Mastodon."
-  landing_strip_signup_html: Ако нямаш акаунт, можеш да си <a href="%{sign_up_path}">създадеш ето тук</a>.
   media_attachments:
     validations:
       images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения
       too_many: Не мога да прикача повече от 4 файла
   notification_mailer:
     digest:
-      body: 'Ето кратко резюме на нещата, които се случиха от последното ти посещение в %{instance} на %{since}:'
+      body: Ето кратко резюме на нещата, които се случиха от последното ти посещение на %{since}
       mention: "%{name} те спомена в:"
       new_followers_summary:
         one: Имаш един нов последовател! Ура!
@@ -144,7 +135,6 @@ bg:
       public: Публично
       unlisted: Публично, но не показвай в публичния канал
   stream_entries:
-    click_to_show: Покажи
     reblogged: споделено
     sensitive_content: Деликатно съдържание
   time:
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index ecf28f26c5f7fec9c11a27f1c22c03a72031b262..9b76d184b8fb2ef4c37aa9b942d5da27c20bdbeb 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -5,13 +5,13 @@ ca:
     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
     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à.
     contact: Contacte
     contact_missing: No configurat
     contact_unavailable: N/D
-    description_headline: Què es %{domain}?
-    domain_count_after: altres instàncies
-    domain_count_before: Connectada a
+    documentation: Documentació
     extended_description_html: |
       <h3>Un bon lloc per les regles</h3>
       <p>Encara no s'ha configurat la descripció ampliada.</p>
@@ -28,25 +28,41 @@ ca:
     hosted_on: Mastodon allotjat a %{domain}
     learn_more: Més informació
     other_instances: Altres instàncies
+    privacy_policy: Política de privacitat
     source_code: Codi font
-    status_count_after: estats
+    status_count_after:
+      one: estat
+      other: estats
     status_count_before: Que han escrit
-    user_count_after: usuaris registrats
+    terms: Termes del servei
+    user_count_after:
+      one: usuari
+      other: usuaris
     user_count_before: Tenim
     what_is_mastodon: Què és Mastodon?
   accounts:
+    choices_html: 'Eleccions de %{name}:'
     follow: Segueix
-    followers: Seguidors
+    followers:
+      one: Seguidor
+      other: Seguidors
     following: Seguint
+    joined: Unit des de %{date}
+    last_active: darrer actiu
+    link_verified_on: La propietat d'aquest enllaç s'ha verificat el %{date}
     media: Mèdia
     moved_html: "%{name} s'ha mogut a %{new_profile_link}:"
     network_hidden: Aquesta informació no està disponible
     nothing_here: No hi ha res aquí!
     people_followed_by: Usuaris seguits per %{name}
     people_who_follow: Usuaris que segueixen %{name}
-    posts: Toots
+    pin_errors:
+      following: Has d'estar seguint la persona que vulguis avalar
+    posts:
+      one: Toot
+      other: Toots
+    posts_tab_heading: Toots
     posts_with_replies: Toots i respostes
-    remote_follow: Seguiment remot
     reserved_username: El nom d'usuari està reservat
     roles:
       admin: Administrador
@@ -54,6 +70,9 @@ ca:
       moderator: Moderador
     unfollow: Deixa de seguir
   admin:
+    account_actions:
+      action: Realitzar acció
+      title: Fer l'acció de moderació a %{acct}
     account_moderation_notes:
       create: Crea nota
       created_msg: La nota de moderació s'ha creat correctament!
@@ -67,12 +86,13 @@ ca:
         changed_msg: El correu electrònic del compte s'ha canviat correctament!
         current_email: Correu electrònic actual
         label: Canviar l'adreça de correu
-        new_email: Nou correu
+        new_email: Nova adreça de correu
         submit: Canviar adreça de correu
         title: Canviar adreça de correu de %{username}
       confirm: Confirma
       confirmed: Confirmat
       confirming: Confirmant
+      deleted: Esborrats
       demote: Degrada
       disable: Inhabilita
       disable_two_factor_authentication: Desactiva 2FA
@@ -88,8 +108,11 @@ ca:
       followers: Seguidors
       followers_url: URL dels seguidors
       follows: Segueix
+      header: Capçalera
       inbox_url: URL de la safata d'entrada
+      invited_by: Convidat per
       ip: IP
+      joined: Unit
       location:
         all: Tot
         local: Local
@@ -99,6 +122,7 @@ ca:
       media_attachments: Adjunts multimèdia
       memorialize: Converteix-lo en memorial
       moderation:
+        active: Actiu
         all: Tot
         silenced: Silenciat
         suspended: Suspès
@@ -106,20 +130,18 @@ ca:
       moderation_notes: Notes de moderació
       most_recent_activity: Activitat més recent
       most_recent_ip: IP més recent
+      no_limits_imposed: Sense límits imposats
       not_subscribed: No subscrit
-      order:
-        alphabetic: Alfabètic
-        most_recent: Més recent
-        title: Ordre
       outbox_url: URL de la bústia de sortida
-      perform_full_suspension: Aplica una suspensió completa
+      perform_full_suspension: Suspèn
       profile_url: URL del perfil
       promote: Promociona
       protocol: Protocol
       public: Públic
       push_subscription_expires: La subscripció PuSH expira
-      redownload: Actualitza l'avatar
+      redownload: Actualitza el perfil
       remove_avatar: Eliminar avatar
+      remove_header: Treu la capçalera
       resend_confirmation:
         already_confirmed: Este usuario ya está confirmado
         send: Reenviar el correu electrònic de confirmació
@@ -137,28 +159,32 @@ ca:
       search: Cerca
       shared_inbox_url: URL de la safata d'entrada compartida
       show:
-        created_reports: Informes creats per aquest compte
-        report: informe
-        targeted_reports: Informes realitzats sobre aquest compte
+        created_reports: Informes creats
+        targeted_reports: Informes realitzats per altres
       silence: Silenci
+      silenced: Silenciat
       statuses: Estats
       subscribe: Subscriu
+      suspended: Suspès
       title: Comptes
       unconfirmed_email: Correu electrònic sense confirmar
       undo_silenced: Deixa de silenciar
       undo_suspension: Desfés la suspensió
       unsubscribe: Cancel·la la subscripció
       username: Nom d'usuari
+      warn: Avís
       web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} han assignat l'informe %{target} a ells mateixos"
         change_email_user: "%{name} ha canviat l'adreça de correu electrònic del usuari %{target}"
         confirm_user: "%{name} ha confirmat l'adreça de correu electrònic de l'usuari %{target}"
+        create_account_warning: "%{name} ha enviat un avís a %{target}"
         create_custom_emoji: "%{name} ha pujat un nou emoji %{target}"
         create_domain_block: "%{name} ha blocat el domini %{target}"
         create_email_domain_block: "%{name} ha afegit a la llista negra el domini del correu electrònic %{target}"
         demote_user: "%{name} ha degradat l'usuari %{target}"
+        destroy_custom_emoji: "%{name} ha destruït l'emoji %{target}"
         destroy_domain_block: "%{name} ha desblocat el domini %{target}"
         destroy_email_domain_block: "%{name} ha afegit a la llista negra el domini de correu electrònic %{target}"
         destroy_status: "%{name} eliminat l'estat per %{target}"
@@ -180,6 +206,7 @@ ca:
         unsuspend_account: "%{name} ha llevat la suspensió del compte de %{target}"
         update_custom_emoji: "%{name} ha actualitzat l'emoji %{target}"
         update_status: "%{name} estat actualitzat per %{target}"
+      deleted_status: "(toot suprimit)"
       title: Registre d'auditoria
     custom_emojis:
       by_domain: Domini
@@ -206,8 +233,30 @@ ca:
       update_failed_msg: No s'ha pogut actualitzar aquest emoji
       updated_msg: Emoji s'ha actualitzat correctament!
       upload: Carrega
+    dashboard:
+      backlog: treballs en espera
+      config: Configuració
+      feature_deletions: Supressions del compte
+      feature_invites: Enllaços de convits
+      feature_profile_directory: Directori de perfils
+      feature_registrations: Registres
+      feature_relay: Relay de la Federació
+      features: Característiques
+      hidden_service: Federació amb serveis ocults
+      open_reports: informes oberts
+      recent_users: Usuaris recents
+      search: Cerca de text complet
+      single_user_mode: Mode d'usuari únic
+      software: Programari
+      space: Ús d’espai
+      title: Panell
+      total_users: usuaris en total
+      trends: Tendències
+      week_interactions: interaccions d'aquesta setmana
+      week_users_active: usuaris actius aquesta setmana
+      week_users_new: nous usuaris aquest setmana
     domain_blocks:
-      add_new: Afegeix
+      add_new: Afegir nou bloqueig de domini
       created_msg: El bloqueig de domini ara s'està processant
       destroyed_msg: El bloqueig de domini s'ha desfet
       domain: Domini
@@ -222,11 +271,13 @@ ca:
         title: Bloqueig de domini nou
       reject_media: Rebutja els fitxers multimèdia
       reject_media_hint: Elimina els fitxers multimèdia emmagatzemats localment i impedeix baixar-ne cap en el futur. Irrellevant en les suspensions
-      severities:
-        noop: Cap
-        silence: Silenci
-        suspend: Suspensió
-      severity: Severitat
+      reject_reports: Rebutja informes
+      reject_reports_hint: Ignora tots els informes procedents d'aquest domini. No és rellevant per a les suspensions
+      rejecting_media: rebutjant els fitxers multimèdia
+      rejecting_reports: rebutjant els informes
+      severity:
+        silence: silenciat
+        suspend: suspès
       show:
         affected_accounts:
           one: Un compte afectat en la base de dades
@@ -236,8 +287,7 @@ ca:
           suspend: Desfés la suspensió de tots els comptes d'aquest domini
         title: Desfés el bloqueig de domini de %{domain}
         undo: Desfés
-      title: Bloquejos de domini
-      undo: Desfés
+      undo: Desfés el bloqueig del domini
     email_domain_blocks:
       add_new: Afegeix
       created_msg: S'ha creat el bloc de domini de correu electrònic
@@ -248,19 +298,47 @@ ca:
         create: Afegeix un domini
         title: Nova adreça de correu en la llista negra
       title: Llista negra de correus electrònics
+    followers:
+      back_to_account: Tornar al compte
+      title: Seguidors de %{acct}
     instances:
-      account_count: Comptes coneguts
-      domain_name: Domini
-      reset: Restableix
-      search: Cerca
-      title: Instàncies conegudes
+      delivery_available: El lliurament està disponible
+      known_accounts:
+        one: "%{count} compte conegut"
+        other: "%{count} comptes coneguts"
+      moderation:
+        all: Totes
+        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_storage: Adjunts multimèdia
     invites:
+      deactivate_all: Desactiva-ho tot
       filter:
         all: Totes
         available: Disponible
         expired: Caducat
         title: Filtre
       title: Convida
+    relays:
+      add_new: Afegiu un nou relay
+      delete: Esborra
+      description_html: Un <strong>relay de federació</strong> és un servidor intermediari que intercanvia grans volums de toots públics entre servidors que es subscriuen i publiquen en ell. <strong>Pot ajudar a servidors petits i mitjans a descobrir contingut del fedivers</strong>, no fent necessari que els usuaris locals manualment segueixin altres persones de servidors remots.
+      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.
+      enabled: Activat
+      inbox_url: URL del Relay
+      pending: S'està esperant l'aprovació del relay
+      save_and_enable: Desa i activa
+      setup: Configura una connexió de relay
+      status: Estat
+      title: Relays
     report_notes:
       created_msg: La nota del informe s'ha creat correctament!
       destroyed_msg: La nota del informe s'ha esborrat correctament!
@@ -275,7 +353,6 @@ ca:
       comment:
         none: Cap
       created_at: Reportat
-      id: ID
       mark_as_resolved: Marca com a resolt
       mark_as_unresolved: Marcar sense resoldre
       notes:
@@ -286,20 +363,15 @@ ca:
         placeholder: Descriu les accions que s'han pres o qualsevol altra actualització relacionada…
       reopen: Reobrir informe
       report: 'Informe #%{id}'
-      report_contents: Contingut
       reported_account: Compte reportat
       reported_by: Reportat per
       resolved: Resolt
       resolved_msg: Informe resolt amb èxit!
-      silence_account: Silencia el compte
       status: Estat
-      suspend_account: Suspèn el compte
-      target: Objectiu
       title: Informes
       unassign: Treure assignació
       unresolved: No resolt
       updated_at: Actualitzat
-      view: Visualització
     settings:
       activity_api_enabled:
         desc_html: Compte d'estatus publicats localment, usuaris actius i registres nous en períodes setmanals
@@ -310,12 +382,24 @@ ca:
       contact_information:
         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
         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
+      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
+      profile_directory:
+        desc_html: Permet als usuaris ser descoberts
+        title: Habilita el directori de perfils
       registrations:
         closed_message:
           desc_html: Apareix en la primera pàgina quan es tanquen els registres. Pots utilitzar etiquetes HTML
@@ -341,6 +425,9 @@ ca:
       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
         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
       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
@@ -362,6 +449,7 @@ ca:
       media:
         title: Contingut multimèdia
       no_media: Sense contingut multimèdia
+      no_status_selected: No s’han canviat els estatus perquè cap no ha estat seleccionat
       title: Estats del compte
       with_media: Amb contingut multimèdia
     subscriptions:
@@ -371,7 +459,21 @@ ca:
       last_delivery: Últim lliurament
       title: WebSub
       topic: Tema
+    tags:
+      accounts: Comptes
+      hidden: Amagat
+      hide: Ocult del directori
+      name: Etiqueta
+      title: Etiquetes
+      unhide: Mostra en el directori
+      visible: Visible
     title: Administració
+    warning_presets:
+      add_new: Afegir nou
+      delete: Esborra
+      edit: Edita
+      edit_preset: Edita l'avís predeterminat
+      title: Gestiona les configuracions predefinides dels avisos
   admin_mailer:
     new_report:
       body: "%{reporter} ha informat de %{target}"
@@ -393,7 +495,7 @@ 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: En inscriure't, acceptes seguir <a href="%{rules_path}">els nostres termes del servei</a> i <a href="%{terms_path}">la nostra política de privadesa</a>.
+    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>.
     change_password: Contrasenya
     confirm_email: Confirmar correu electrònic
     delete_account: Suprimeix el compte
@@ -449,6 +551,16 @@ ca:
     success_msg: El compte s'ha eliminat correctament
     warning_html: Només és garantida l'eliminació d'aquesta particular instància. El contingut que s'ha compartit àmpliament deixa petjades. Els servidors fora de línia i els que ja no estan subscrits no actualitzaran les seves bases de dades.
     warning_title: Disponibilitat de contingut disseminat
+  directories:
+    directory: Directori de perfils
+    enabled: Actualment estàs inclòs al directori.
+    enabled_but_waiting: Has optat per aparèixer al directori però encara no tens el nombre mínim de seguidors (%{min_followers}) per ser-hi.
+    explanation: Descobreix usuaris segons els seus interessos
+    explore_mastodon: Explora %{title}
+    how_to_enable: Actualment no tens activat ser al directori. Pots optar-hi a continuació. Utilitza etiquetes en el teu text bio per incloure't sota etiquetes especifiques!
+    people:
+      one: "%{count} persona"
+      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.
@@ -460,7 +572,7 @@ ca:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md"> aplicacions natives</a> de Mastodon per a la vostra plataforma.
+    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.
   exports:
     archive_takeout:
       date: Data
@@ -471,7 +583,9 @@ ca:
       size: Tamany
     blocks: Persones que has blocat
     csv: CSV
+    domain_blocks: Bloquejos de dominis
     follows: Persones que segueixes
+    lists: Llistes
     mutes: Persones silenciades
     storage: Emmagatzematge
   filters:
@@ -502,9 +616,13 @@ ca:
     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:
     changes_saved_msg: Els canvis s'han desat correctament!
-    powered_by: amb tecnologia %{link}
+    copy: Copia
     save_changes: Desa els canvis
     validation_errors:
       one: Alguna cosa no va bé! Si us plau, revisa l'error
@@ -540,8 +658,6 @@ ca:
       expires_at: Caduca
       uses: Usos
     title: Convida persones
-  landing_strip_html: "<strong>%{name}</strong> és un usuari/a de %{link_to_root_path}. Pots seguir-lo/la o interactuar amb ell/a si tens un compte a qualsevol node del fediverse."
-  landing_strip_signup_html: Si no en tens, pots <a href="%{sign_up_path}">registrar-te aquí</a>.
   lists:
     errors:
       limit: Has assolit la quantitat màxima de llistes
@@ -559,7 +675,7 @@ ca:
   notification_mailer:
     digest:
       action: Veure totes les notificacions
-      body: Un resum del que et vas perdre en %{instance} desde la darrera visita el %{since}
+      body: Un resum del que et vas perdre desde la darrera visita el %{since}
       mention: "%{name} t'ha mencionat en:"
       new_followers_summary:
         one: A més, has adquirit un nou seguidor durant la teva absència! Visca!
@@ -588,7 +704,7 @@ ca:
       title: Menció nova
     reblog:
       body: "%{name} ha impulsat el teu estat:"
-      subject: "%{name} ha retootejat el teu estat"
+      subject: "%{name} ha impulsat el teu estat"
       title: Nou impuls
   number:
     human:
@@ -618,10 +734,25 @@ ca:
     no_account_html: No tens cap compte? Pots <a href='%{sign_up_path}' target='_blank'>registrar-te aquí</a>
     proceed: Comença a seguir
     prompt: 'Seguiràs a:'
+    reason_html: "<strong>Per què és necessari aquest pas?</strong> <code>%{instance}</code> pot ser que no sigui el servidor on estàs registrat per tant primer hem de redirigir-te al teu servidor."
+  remote_interaction:
+    favourite:
+      proceed: Procedir a afavorir
+      prompt: 'Vols marcar com a favorit aquest toot:'
+    reblog:
+      proceed: Procedir a impulsar
+      prompt: 'Vols impulsar aquest toot:'
+    reply:
+      proceed: Procedir a respondre
+      prompt: 'Vols respondre a aquest toot:'
   remote_unfollow:
     error: Error
     title: Títol
     unfollowed: Sense seguir
+  scheduled_statuses:
+    over_daily_limit: Has superat el límit de %{limit} toots programats per a aquell dia
+    over_total_limit: Has superat el limit de %{limit} toots programats
+    too_soon: La data programada ha de ser futura
   sessions:
     activity: Última activitat
     browser: Navegador
@@ -701,6 +832,7 @@ ca:
       private: No es pot fixar el toot no públic
       reblog: No es pot fixar un impuls
     show_more: Mostrar més
+    sign_in_to_participate: Inicia la sessió per participar a la conversa
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Només seguidors
@@ -710,7 +842,6 @@ ca:
       unlisted: No llistat
       unlisted_long: Tothom ho pot veure, però no es mostra en la història federada
   stream_entries:
-    click_to_show: Clic per mostrar
     pinned: Toot fixat
     reblogged: ha impulsat
     sensitive_content: Contingut sensible
@@ -804,6 +935,7 @@ ca:
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Introdueix el codi generat per l'aplicació autenticadora per a confirmar
     description_html: Si habilites l'<strong>autenticació de dos factors</strong>, et caldrà tenir el teu telèfon, que generarà tokens per a que puguis iniciar sessió.
@@ -825,6 +957,22 @@ ca:
       explanation: Has sol·licitat una copia completa del teu compte Mastodon. Ara ja està a punt per descàrrega!
       subject: El teu arxiu està preparat per a descàrrega
       title: Recollida del arxiu
+    warning:
+      explanation:
+        disable: Mentre el teu compte estigui congelat les dades romandran intactes però no pots dur a terme cap acció fins que no estigui desbloquejat.
+        silence: Mentre el teu compte estigui limitat només les persones que ja et segueixen veuen les teves dades en aquest servidor i pots ser exclòs de diverses llistes públiques. No obstant això, d'altres encara poden seguir-te manualment.
+        suspend: El teu compte s'ha suspès i tots els teus toots i fitxers multimèdia penjats s'han eliminat irreversiblement d'aquest servidor i dels servidors on tenies seguidors.
+      review_server_policies: Revisa les polítiques del servidor
+      subject:
+        disable: S'ha congelat el teu compte %{acct}
+        none: Avís per a %{acct}
+        silence: El teu compte %{acct} ha estat limitat
+        suspend: S'ha suspès el teu compte %{acct}
+      title:
+        disable: Compte congelat
+        none: Avís
+        silence: Compte limitat
+        suspend: Compte suspès
     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.
@@ -836,7 +984,6 @@ ca:
       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
-      tip_bridge_html: Si vens de Twitter, pots trobar els teus amics a Mastodon mitjançant l'aplicació <a href="%{bridge_url}"> bridge </a>. Només funciona si també ells usen aquesta aplicació pont!
       tip_federated_timeline: La línia de temps federada és el cabal principal de la xarxa Mastodon. Però només inclou les persones a les quals els teus veïns estan subscrits, de manera que no està complet.
       tip_following: Per defecte segueixes als administradors del servidor. Per trobar més persones interessants, consulta les línies de temps local i federada.
       tip_local_timeline: La línia de temps local és la vista del flux de publicacions dels usuaris de %{instance}. Aquests usuaris són els teus veïns més propers!
@@ -844,8 +991,12 @@ ca:
       tips: Consells
       title: Benvingut a bord, %{name}!
   users:
+    follow_limit_reached: No pots seguir més de %{limit} persones
     invalid_email: L'adreça de correu no és correcta
     invalid_otp_token: El codi de dos factors no és correcte
     otp_lost_help_html: Si has perdut l'accés a tots dos pots contactar per %{email}
     seamless_external_login: Has iniciat sessió via un servei extern per tant els ajustos de contrasenya i correu electrònic no estan disponibles.
     signed_in_as: 'Sessió iniciada com a:'
+  verification:
+    explanation_html: 'Pots <strong>verificar-te com a propietari dels enllaços a les metadades del teu perfil</strong>. Per això, el lloc web enllaçat ha de contenir un enllaç al teu perfil de Mastodon. El vincle <strong>ha de</strong> tenir l''atribut <code>rel="me"</code>. El contingut del text de l''enllaç no importa. Aquí tens un exemple:'
+    verification: Verificació
diff --git a/config/locales/co.yml b/config/locales/co.yml
index eba483215653fb747dc77712dcefcbf2dfa76a65..d27875d91ff1a90f35900337afe23d364316bc48 100644
--- a/config/locales/co.yml
+++ b/config/locales/co.yml
@@ -5,13 +5,13 @@ co:
     about_mastodon_html: Mastodon ghjè una rete suciale custruita incù prutucolli web aperti è lugiziali liberi. Hè decentralizatu cumu l’e-mail.
     about_this: À prupositu
     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à.
     contact: Cuntattu
     contact_missing: Mancante
     contact_unavailable: Micca dispunibule
-    description_headline: Quale hè %{domain} ?
-    domain_count_after: altre istanze
-    domain_count_before: Cunnettati à
+    documentation: Ducumentazione
     extended_description_html: |
       <h3>Una bona piazza per e regule</h3>
       <p>A descrizzione stesa ùn hè micca stata riempiuta.</p>
@@ -28,25 +28,41 @@ co:
     hosted_on: Mastodon allughjatu nant’à %{domain}
     learn_more: Amparà di più
     other_instances: Lista di l’istanze
+    privacy_policy: Pulitica di vita privata
     source_code: Codice di fonte
-    status_count_after: statuti
+    status_count_after:
+      one: statutu
+      other: statuti
     status_count_before: chì anu pubblicatu
-    user_count_after: parsone quì
+    terms: Cundizione di u serviziu
+    user_count_after:
+      one: utilizatore
+      other: utilizatori
     user_count_before: Ci sò
     what_is_mastodon: Quale hè Mastodon?
   accounts:
+    choices_html: "%{name} ricumanda:"
     follow: Siguità
-    followers: Abbunati
+    followers:
+      one: Abbunatu·a
+      other: Abbunati
     following: Abbunamenti
+    joined: Quì dapoi %{date}
+    last_active: ultima attività
+    link_verified_on: A pruprietà d'issu ligame hè stata verificata u %{date}
     media: Media
     moved_html: "%{name} hà cambiatu di contu, avà hè nant’à %{new_profile_link}:"
     network_hidden: St'infurmazione ùn hè micca dispunibule
     nothing_here: Ùn c’hè nunda quì!
     people_followed_by: Seguitati da %{name}
     people_who_follow: Seguitanu %{name}
-    posts: Statuti
+    pin_errors:
+      following: Duvete digià siguità a persona che vulete ricumandà
+    posts:
+      one: Statutu
+      other: Statuti
+    posts_tab_heading: Statuti
     posts_with_replies: Statuti è risposte
-    remote_follow: Siguità d’altrò
     reserved_username: Stu cugnome hè riservatu
     roles:
       admin: Amministratore
@@ -54,6 +70,9 @@ co:
       moderator: Muderatore
     unfollow: Ùn siguità più
   admin:
+    account_actions:
+      action: Realizà un'azzione
+      title: Realizà un'azzione di muderazione nant'à %{acct}
     account_moderation_notes:
       create: Creà
       created_msg: Nota di muderazione creata!
@@ -65,14 +84,15 @@ co:
       by_domain: Duminiu
       change_email:
         changed_msg: Email di u contu cambiatu!
-        current_email: Email attuale
-        label: Mudificà l’Email
-        new_email: Novu Email
-        submit: Cambià Email
-        title: Mudificà l’Email di %{username}
+        current_email: E-mail attuale
+        label: Mudificà l’e-mail
+        new_email: Novu e-mail
+        submit: Cambià l'e-mail
+        title: Mudificà l’e-mail di %{username}
       confirm: Cunfirmà
       confirmed: Cunfirmata
       confirming: Cunfirmazione
+      deleted: Sguassatu
       demote: Ritrugradà
       disable: Disattivà
       disable_two_factor_authentication: Disattivà l’identificazione à 2 fattori
@@ -81,15 +101,18 @@ co:
       domain: Duminiu
       edit: Mudificà
       email: E-mail
-      email_status: Statu di l’e-mail
+      email_status: Statutu di l’e-mail
       enable: Attivà
       enabled: Attivatu
       feed_url: URL di u flussu
       followers: Abbunati
       followers_url: URL di l’abbunati
       follows: Abbunamenti
+      header: Intistatura
       inbox_url: URL di l’inbox
+      invited_by: Invitatu da
       ip: IP
+      joined: Ghjuntu
       location:
         all: Tutti
         local: Lucale
@@ -99,6 +122,7 @@ co:
       media_attachments: Media aghjunti
       memorialize: Trasfurmà in mimuriale
       moderation:
+        active: Attivu
         all: Tutti
         silenced: Silenzati
         suspended: Suspesi
@@ -106,20 +130,18 @@ co:
       moderation_notes: Note di muderazione
       most_recent_activity: Attività più ricente
       most_recent_ip: IP più ricente
+      no_limits_imposed: Nisuna limita imposta
       not_subscribed: Micca abbunatu
-      order:
-        alphabetic: Alfabeticu
-        most_recent: Più ricente
-        title: Urdine
       outbox_url: URL di l’outbox
-      perform_full_suspension: Fà una suspensione cumpleta
+      perform_full_suspension: Suspende
       profile_url: URL di u prufile
       promote: Prumove
       protocol: Prutucollu
       public: Pubblicu
       push_subscription_expires: Spirata di l’abbunamentu PuSH
-      redownload: Mette à ghjornu i ritratti
+      redownload: Mette à ghjornu u prufile
       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
@@ -137,28 +159,32 @@ co:
       search: Cercà
       shared_inbox_url: URL di l’inbox spartuta
       show:
-        created_reports: Signalamenti creati da stu contu
-        report: Signalamentu
-        targeted_reports: Signalamenti creati contr’à stu contu
+        created_reports: Signalamenti fatti
+        targeted_reports: Signalatu da l'altri
       silence: Silenzà
+      silenced: Silenzatu
       statuses: Statuti
       subscribe: Abbunassi
+      suspended: Suspesu
       title: Conti
       unconfirmed_email: E-mail micca cunfirmatu
       undo_silenced: Ùn silenzà più
       undo_suspension: Ùn suspende più
       unsubscribe: Disabbunassi
       username: Cugnome
+      warn: Averte
       web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} s’hè assignatu u signalamentu %{target}"
         change_email_user: "%{name} hà cambiatu l’indirizzu e-mail di %{target}"
         confirm_user: "%{name} hà cunfirmatu l’indirizzu e-mail di %{target}"
+        create_account_warning: "%{name} hà mandatu un'avertimentu à %{target}"
         create_custom_emoji: "%{name} hà caricatu una nov’emoji %{target}"
         create_domain_block: "%{name} hà bluccatu u duminiu %{target}"
         create_email_domain_block: "%{name} hà messu u duminiu e-mail %{target} nant’a lista nera"
         demote_user: "%{name} hà ritrugradatu l’utilizatore %{target}"
+        destroy_custom_emoji: "%{name} hà sguassatu l'emoji %{target}"
         destroy_domain_block: "%{name} hà sbluccatu u duminiu %{target}"
         destroy_email_domain_block: "%{name} hà messu u duminiu e-mail %{target} nant’a lista bianca"
         destroy_status: "%{name} hà toltu u statutu di %{target}"
@@ -180,6 +206,7 @@ co:
         unsuspend_account: "%{name} hà fattu che u contu di %{target} ùn hè più suspesu"
         update_custom_emoji: "%{name} hà messu à ghjornu l’emoji %{target}"
         update_status: "%{name} hà cambiatu u statutu di %{target}"
+      deleted_status: "(statutu sguassatu)"
       title: Ghjurnale d’audit
     custom_emojis:
       by_domain: Duminiu
@@ -206,8 +233,30 @@ co:
       update_failed_msg: Ùn s’hè micca pussutu mette à ghjornu l’emoji
       updated_msg: L’emoji hè stata messa à ghjornu!
       upload: Caricà
+    dashboard:
+      backlog: travagli in attesa
+      config: Cunfigurazione
+      feature_deletions: Sguassamenti di conti
+      feature_invites: Ligami d'invitazione
+      feature_profile_directory: Annuariu di i prufili
+      feature_registrations: Arregistramenti
+      feature_relay: Ripetitore di federazione
+      features: Funziunalità
+      hidden_service: Federazione cù servizii piattati
+      open_reports: signalamenti aperti
+      recent_users: Utilizatori ricenti
+      search: Ricerca di testu sanu
+      single_user_mode: Modu utilizatore unicu
+      software: Lugiziale
+      space: Usu di u spaziu
+      title: Dashboard
+      total_users: utilizatori in tutale
+      trends: Tindenze
+      week_interactions: interazzione sta settimana
+      week_users_active: attivi sta settimana
+      week_users_new: utilizatori sta settimana
     domain_blocks:
-      add_new: Aghjustà
+      add_new: Aghjustà novu blucchime di duminiu
       created_msg: U blucchime di u duminiu hè attivu
       destroyed_msg: U blucchime di u duminiu ùn hè più attivu
       domain: Duminiu
@@ -215,18 +264,20 @@ co:
         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.
         severity:
-          desc_html: Cù<strong>Silenzà</strong>, solu l’abbunati di u contu viderenu i so missaghji. <strong>Suspende</strong> sguassarà tutti i cuntenuti è dati di u contu. Utilizate <strong>Nisuna</strong> s’è voi vulete solu righjittà fugliali media.
+          desc_html: Cù <strong>Silenzà</strong>, solu l’abbunati di u contu viderenu i so missaghji. <strong>Suspende</strong> sguassarà tutti i cuntenuti è dati di u contu. Utilizate <strong>Nisuna</strong> s’è voi vulete solu righjittà fugliali media.
           noop: Nisuna
           silence: Silenzà
           suspend: Suspende
         title: Novu blucchime di duminiu
       reject_media: Righjittà i fugliali media
       reject_media_hint: Sguassa tutti i media caricati è ricusa caricamenti futuri. Inutile per una suspensione
-      severities:
-        noop: Nisuna
-        silence: Silenzà
-        suspend: Suspende
-      severity: Severità
+      reject_reports: Righjittà i rapporti
+      reject_reports_hint: Ignurà tutti i signalamenti chì venenu d'issu duminiu. Senz'oghjettu pè e suspensione
+      rejecting_media: righjettu di i fugliali media
+      rejecting_reports: righjettu di i signalamenti
+      severity:
+        silence: silenzatu
+        suspend: suspesu
       show:
         affected_accounts:
           one: Un contu tuccatu indè a database
@@ -236,8 +287,7 @@ co:
           suspend: Ùn suspende più i conti nant’à stu duminiu
         title: Ùn bluccà più u duminiu %{domain}
         undo: Annullà
-      title: Blucchimi di duminiu
-      undo: Annullà
+      undo: Annullà u blucchime di duminiu
     email_domain_blocks:
       add_new: Aghjustà
       created_msg: U blucchime di u duminiu d’e-mail hè attivu
@@ -248,19 +298,47 @@ co:
         create: Creà un blucchime
         title: Nova iscrizzione nant’a lista nera e-mail
       title: Lista nera e-mail
+    followers:
+      back_to_account: Rivene à u Contu
+      title: Abbunati à %{acct}
     instances:
-      account_count: Conti cunnisciuti
-      domain_name: Duminiu
-      reset: Riinizializà
-      search: Cercà
-      title: Istanze cunnisciute
+      delivery_available: Rimessa dispunibule
+      known_accounts:
+        one: "%{count} contu cunnisciutu"
+        other: "%{count} conti cunnisciuti"
+      moderation:
+        all: Tuttu
+        limited: Limitatu
+        title: Muderazione
+      title: Federazione
+      total_blocked_by_us: Bluccati da noi
+      total_followed_by_them: Siguitati da elli
+      total_followed_by_us: Siguitati da noi
+      total_reported: Rapporti nant'à elli
+      total_storage: Media aghjunti
     invites:
+      deactivate_all: Disattivà tuttu
       filter:
         all: Tuttu
         available: Dispunibuli
         expired: Spirati
         title: Filtrà
       title: Invitazione
+    relays:
+      add_new: Aghjustà un ripetitore
+      delete: Sguassà
+      description_html: Un <strong>ripetitore di federazione</strong> ghjè un servore intermediariu chì manda statuti pubblichi trà l'istanze abbunate. <strong>Pò aiutà l'istanze chjuche è mezane à scuprì u cuntinutu di u fediverse</strong> senza chì l'utilizatori appianu bisognu di seguità tutti i conti di l'altri servori.
+      disable: Disattivà
+      disabled: Disattivatu
+      enable: Attivà
+      enable_hint: Quandu sarà attivatu, u vostru servore hà da seguità i statuti pubblichi di u ripetitore, è mandarà i so statuti pubblichi quallà.
+      enabled: Attivatu
+      inbox_url: URL di u ripetitore
+      pending: In attesa di l'apprubazione di u ripetitore
+      save_and_enable: Salvà è attivà
+      setup: Creà una cunnessione cù un ripetitore
+      status: Statutu
+      title: Ripetitori
     report_notes:
       created_msg: Nota di signalamentu creata!
       destroyed_msg: Nota di signalamentu sguassata!
@@ -275,7 +353,6 @@ co:
       comment:
         none: Nisunu
       created_at: Palisatu
-      id: ID
       mark_as_resolved: Indicà cum’è chjosu
       mark_as_unresolved: Indicà cum’è sempre apertu
       notes:
@@ -286,20 +363,15 @@ co:
         placeholder: Per parlà di l’azzione pigliate, o altre messe à ghjornu nant’à u signalamentu…
       reopen: Riapre u signalamentu
       report: 'Signalamente #%{id}'
-      report_contents: Cuntenuti
       reported_account: Contu palisatu
       reported_by: Palisatu da
       resolved: Scioltu è chjosu
       resolved_msg: Signalamentu scioltu!
-      silence_account: Silenzà u contu
       status: Statutu
-      suspend_account: Suspende u contu
-      target: Oggettu
       title: Signalamenti
       unassign: Disassignà
       unresolved: Micca sciolti
       updated_at: Messi à ghjornu
-      view: Vede
     settings:
       activity_api_enabled:
         desc_html: Numeri di statuti creati quì, utilizatori attivi, è arregistramenti novi tutte e settimane
@@ -310,18 +382,30 @@ co:
       contact_information:
         email: E-mail prufissiunale
         username: Identificatore di cuntattu
+      custom_css:
+        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
         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
+      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
+      profile_directory:
+        desc_html: Auturizà a scuperta di l'utilizatori
+        title: Attivà l'annuariu di i prufili
       registrations:
         closed_message:
           desc_html: Affissatu nant’a pagina d’accolta quandu l’arregistramenti sò chjosi. Pudete fà usu di u furmattu HTML
           title: Missaghju per l’arregistramenti chjosi
         deletion:
-          desc_html: Auturizà tuttu u mondu di sguassà u so propiu contu
+          desc_html: Auturizà tuttu u mondu à sguassà u so propiu contu
           title: Auturizà à sguassà i conti
         min_invite_role:
           disabled: Nisunu
@@ -336,11 +420,14 @@ co:
         desc_html: Mustrerà un badge Squadra nant’à un prufile d’utilizatore
         title: Mustrà un badge staff
       site_description:
-        desc_html: Paragrafu di prisentazione nant’a pagina d’accolta è i marchi meta. Pudete fà usu di marchi HTML, in particulare <code>&lt;a&gt;</code> è <code>&lt;em&gt;</code>.
+        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
       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
       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
@@ -362,6 +449,7 @@ co:
       media:
         title: Media
       no_media: Nisun media
+      no_status_selected: I statuti ùn sò micca stati mudificati perchè manc'unu era selezziunatu
       title: Statutu di u contu
       with_media: Cù media
     subscriptions:
@@ -371,7 +459,21 @@ co:
       last_delivery: Ultima arricata
       title: WebSub
       topic: Sughjettu
+    tags:
+      accounts: Conti
+      hidden: Piattatu
+      hide: Piattà di l'annuariu
+      name: Hashtag
+      title: Hashtag
+      unhide: Mustrà in l'annuariu
+      visible: Visibile
     title: Amministrazione
+    warning_presets:
+      add_new: Aghjustà nova
+      delete: Sguassà
+      edit: Cambià
+      edit_preset: Cambià a preselezzione d'avertimentu
+      title: Amministrà e preselezzione d'avertimentu
   admin_mailer:
     new_report:
       body: "%{reporter} hà palisatu %{target}"
@@ -393,7 +495,7 @@ co:
     warning: Abbadate à quessi dati. Ùn i date à nisunu!
     your_token: Rigenerà a fiscia d’accessu
   auth:
-    agreement_html: Arregistrassi 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>.
+    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>.
     change_password: Chjave d’accessu
     confirm_email: Cunfirmà l’e-mail
     delete_account: Sguassà u contu
@@ -424,7 +526,7 @@ co:
     following: 'Eccu! Avà seguitate:'
     post_follow:
       close: O pudete ancu chjude sta finestra.
-      return: Rivultà à u prufile di l’utilizatore
+      return: Vede u prufile di l’utilizatore
       web: Andà à l’interfaccia web
     title: Siguità %{acct}
   datetime:
@@ -449,6 +551,13 @@ co:
     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_title: Dispunibilità di i cuntenuti sparsi
+  directories:
+    directory: Annuariu di i prufili
+    explanation: Scopre utilizatori à partesi di i so centri d'interessu
+    explore_mastodon: Scopre à %{title}
+    people:
+      one: "%{count} persona"
+      other: "%{count} persone"
   errors:
     '403': Ùn site micca auturizatu·a à vede sta pagina.
     '404': Sta pagina ùn esiste micca.
@@ -460,7 +569,7 @@ co:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">l’applicazione native</a> per a vostra piattaforma.
+    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.
   exports:
     archive_takeout:
       date: Data
@@ -471,9 +580,27 @@ co:
       size: Pesu
     blocks: Bluccate
     csv: CSV
+    domain_blocks: Blucchime di duminiu
     follows: Seguitate
+    lists: Liste
     mutes: Piattate
     storage: I vostri media
+  filters:
+    contexts:
+      home: Accolta
+      notifications: Nutificazione
+      public: Linee pubbliche
+      thread: Cunversazione
+    edit:
+      title: Mudificà u filtru
+    errors:
+      invalid_context: Micca abbastanza cuntestu
+      invalid_irreversible: A filtrazione irreversibile marchja solu per l'accolta è e nutificazione
+    index:
+      delete: Toglie
+      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.
@@ -486,9 +613,13 @@ co:
     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:
     changes_saved_msg: Cambiamenti salvati!
-    powered_by: mossu da %{link}
+    copy: Cupià
     save_changes: Salvà e mudificazione
     validation_errors:
       one: Qualcosa ùn và bè! Verificate u prublemu quì sottu
@@ -514,6 +645,7 @@ co:
       '86400': 1 ghjornu
     expires_in_prompt: Mai
     generate: Creà
+    invited_by: 'Site statu·a invitatu·a da:'
     max_uses:
       one: 1 usu
       other: "%{count} usi"
@@ -523,8 +655,6 @@ co:
       expires_at: Spira
       uses: Utiliza
     title: Invità ghjente
-  landing_strip_html: "<strong>%{name}</strong> hè nant’à %{link_to_root_path}. Pudete seguitallu·a o cumunicà cù ellu·a cù un contu in qualche parte di u fediverse."
-  landing_strip_signup_html: Pudete ancu <a href="%{sign_up_path}">arrigistravi quì</a>.
   lists:
     errors:
       limit: Ùn pudete più creà altre liste
@@ -598,12 +728,28 @@ co:
   remote_follow:
     acct: Entrate u vostru cugnome@istanza da induve vulete siguità stu contu
     missing_resource: Ùn avemu pussutu à truvà l’indirizzu di ridirezzione
+    no_account_html: Ùn avete micca un contu? Pudete <a href='%{sign_up_path}' target='_blank'>arregistravi quì</a>
     proceed: Cuntinuà per siguità
     prompt: 'Avete da siguità:'
+    reason_html: "<strong>Perchè hè necessaria sta tappa?</strong> <code>%{instance}</code> ùn hè forse micca u servore induve site arregistratu·a, allora primu duvemu riindirizzavi à u vostru servore."
+  remote_interaction:
+    favourite:
+      proceed: Cuntinuà per favurisce
+      prompt: 'Vulete aghjustà stu statutu à i vostri favuriti:'
+    reblog:
+      proceed: Cuntinuà per sparte
+      prompt: 'Vulete sparte stu statutu:'
+    reply:
+      proceed: Cuntinuà per risponde
+      prompt: 'Vulete risponde à stu statutu:'
   remote_unfollow:
     error: Errore
     title: Titulu
     unfollowed: Disabbunatu
+  scheduled_statuses:
+    over_daily_limit: Avete trapassatu a limita di %{limit} statuti planificati per stu ghjornu
+    over_total_limit: Avete trapassatu a limita di %{limit} statuti planificati
+    too_soon: A data deve esse indè u futuru
   sessions:
     activity: Ultima attività
     browser: Navigatore
@@ -674,6 +820,7 @@ co:
     disallowed_hashtags:
       one: 'cuntene l’hashtag disattivatu: %{tags}'
       other: 'cuntene l’hashtag disattivati: %{tags}'
+    language_detection: Truvà a lingua autumaticamente
     open_in_web: Apre nant’à u web
     over_character_limit: Site sopr’à a limita di %{max} caratteri
     pin_errors:
@@ -682,6 +829,7 @@ co:
       private: Ùn pudete micca puntarulà un statutu ch’ùn hè micca pubblicu
       reblog: Ùn pudete micca puntarulà una spartera
     show_more: Vede di più
+    sign_in_to_participate: Cunnettatevi per participà à a cunversazione
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Solu per l’abbunati
@@ -691,11 +839,91 @@ co:
       unlisted: Micca listatu
       unlisted_long: Tuttu u mondu pò vede, mà micca indè e linee pubbliche
   stream_entries:
-    click_to_show: Cliccà per vede
     pinned: Statutu puntarulatu
-    reblogged: spartutu
+    reblogged: hà spartutu
     sensitive_content: Cuntenutu sensibile
   terms:
+    body_html: |
+      <h2>Politique de confidentialité</h2>
+      <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>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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Que faisons-nous des informations que nous collectons ?</h3>
+
+      <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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">Comment protégeons-nous vos informations ?</h3>
+
+      <p>Nous mettons en œuvre une variété de mesures de sécurité afin de garantir la sécurité de vos informations personnelles quand vous les saisissez, les soumettez et les consultez. Entre autres choses, votre session de navigation ainsi que le trafic entre votre application et l’API sont sécurisés à l’aide de TLS tandis que votre mot de passe est haché en utilisant un puissant algorithme à sens unique. Vous pouvez également activer l’authentification à deux facteurs pour sécuriser encore plus l’accès à votre compte.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">Quelle est notre politique de conservation des données ?</h3>
+
+      <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>
+      </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>
+
+      <p>Vous pouvez, à n’importe quel moment, supprimer votre compte de manière définitive.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Utilisons-nous des témoins de connexion ?</h3>
+
+      <p>Oui. Les témoins de connexion sont de petits fichiers qu’un site ou un service transféres sur le disque dur de votre ordinateur via votre navigateur web (si vous l’avez autorisé). Ces témoins permettent au site de reconnaître votre navigateur et de, dans le cas où vous possédez un compte, de vous associer avec ce dernier.</p>
+
+      <p>Nous utilisons les témoins de connexion comme un moyen de comprendre et de nous souvenir de vos préférences pour vos prochaines visites.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Divulguons-nous des informations à des tierces parties ?</h3>
+
+      <p>Nous ne vendons, n’échangeons ou ne transférons d’une quelque manière que soit des informations permettant de vous identifier personnellement. Cela n’inclut pas les tierces parties de confiance qui nous aident à opérer ce site, à conduire nos activités commerciales ou à vous servir, tant qu’elles acceptent de garder ces informations confidentielles. Nous sommes également susceptibles de partager vos informations quand nous pensons que c’est nécessaire pour nous conformer à la loi, pour appliquer les politiques de notre site ainsi que pour défendre nos droits, notre propriété, notre sécurité et celles et ceux d’autres personnes.</p>
+
+      <p>Votre contenu public peut être téléchargé par d’autres serveurs du réseau. Dans le cas où vos abonné·e·s et vos destinataires résideraient sur des serveurs différents du vôtre, vos posts publics et abonné·e·s uniquement peuvent être délivrés vers les serveurs de vos abonné·e·s tandis que vos messages directs sont délivrés aux serveurs de vos destinataires.</p>
+
+      <p>Quand vous autorisez une application à utiliser votre compte, en fonction de l’étendue des permissions que vous approuvez, il est possible qu’elle puisse accéder aux informations publiques de votre profil, votre liste d’abonnements, votre liste d’abonné·e·s, vos listes, tout vos posts et vos favoris. Les applications ne peuvent en aucun cas accéder à votre adresse électronique et à votre mot de passe.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Utilisation de ce site par les enfants</h3>
+
+      <p>Si ce serveur est situé dans dans l’UE ou l’EEE : Notre site, produits et services sont tous destinés à des personnes âgées de 16 ans ou plus. Si vous avez moins de 16 ans, en application du RGPD (<a href="https://fr.wikipedia.org/wiki/R%C3%A8glement_g%C3%A9n%C3%A9ral_sur_la_protection_des_donn%C3%A9es">Règlement Général sur la Protection des Données</a>), merci de ne pas utiliser ce site.</p>
+
+      <p>Si ce serveur est situé dans aux États-Unis d’Amérique : Notre site, produits et services sont tous destinés à des personnes âgées de 13 ans ou plus. Si vous avez moins de 13 ans, en application du COPPA (<a href="https://fr.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>), merci de ne pas utiliser ce site.</p>
+
+      <p>Les exigences légales peuvent être différentes si ce serveur se trouve dans une autre juridiction.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Modifications de notre politique de confidentialité</h3>
+
+      <p>Dans le cas où nous déciderions de changer notre politique de confidentialité, nous posterons les modifications sur cette page.</p>
+
+      <p>Ce document est publié sous lincence CC-BY-SA. Il a été mis à jours pour la dernière fois le 7 mars 2018.</p>
+
+      <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
@@ -704,6 +932,7 @@ co:
   time:
     formats:
       default: "%d %b %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Entrate u codice generatu da l’applicazione per cunfirmà
     description_html: S’ella hè attivata <strong>l’identificazione à dui fattori</strong>, duvete avè u vostru telefuninu pè ottene un codice di cunnezzione.
@@ -725,6 +954,22 @@ co:
       explanation: Avete dumandatu un’archiviu cumpletu di u vostru contu Mastodon. Avà hè prontu per scaricà!
       subject: U vostru archiviu hè prontu à scaricà
       title: Archiviu prontu
+    warning:
+      explanation:
+        disable: Quandu u vostru contu hè ghjacciatu, i vostri dati stannu intatti, mà ùn pudete fà nunda fin'à ch'ellu sia sbluccatu.
+        silence: Quandu u vostru contu hè limitatu, solu quelli chì sò digià abbunati à u vostru contu viderenu i vostri statuti nant'à quessu servore, è puderete esse esclusu·a di parechje liste pubbliche. Però, altri conti puderenu sempre seguitavi.
+        suspend: U vostru contu hè statu suspesu, è tutti i vo statuti è fugliali media caricati sò stati sguassati di manera irreversibile di stu servore, è di i servori induve aviate abbunati.
+      review_server_policies: Leghje e pulitiche di u servore
+      subject:
+        disable: U vostru contu %{acct} hè statu ghjacciatu
+        none: Avertimentu pè %{acct}
+        silence: U vostru contu %{acct} hè statu limitatu
+        suspend: U vostru contu %{acct} hè statu suspesu
+      title:
+        disable: Contu ghjacciatu
+        none: Avertimentu
+        silence: Contu limitatu
+        suspend: Contu suspesu
     welcome:
       edit_profile_action: Cunfigurazione di u prufile
       edit_profile_step: Pudete persunalizà u vostru prufile cù un ritrattu di prufile o di cuprendula, un nome pubblicu persunalizatu, etc. Pudete ancu rende u contu privatu per duvè cunfirmà ogni dumanda d’abbunamentu.
@@ -736,7 +981,6 @@ co:
       review_preferences_action: Mudificà e priferenze
       review_preferences_step: Quì pudete adattà u cumpurtamentu di Mastodon à e vostre priferenze, cum’è l’email che vulete riceve, u nivellu di cunfidenzialità predefinitu di i vostri statuti, o u cumpurtamentu di i GIF animati.
       subject: Benvenutu·a nant’à Mastodon
-      tip_bridge_html: S’è voi venite di Twitter, pudete truvà i vostri amichi da quallà chì sò nant’à Mastodon cù a <a href="%{bridge_url}">bridge app</a>. Mà ùn marchja chè s’elli l’anu ancu usata!
       tip_federated_timeline: A linea pubblica glubale mostra i statuti da altre istanze nant’a rete Mastodon, mà ùn hè micca cumpleta perchè ci sò soli i conti à quelli sò abbunati membri di a vostr’istanza.
       tip_following: Site digià abbunatu·a à l’amministratori di u vostru servore. Per truvà d’altre parsone da siguità, pudete pruvà e linee pubbliche.
       tip_local_timeline: A linea pubblica lucale ghjè una vista crunulogica di i statuti di a ghjente nant’à %{instance}. Quessi sò i vostri cunvicini!
@@ -744,8 +988,12 @@ co:
       tips: Cunsiglii
       title: Benvenutu·a, %{name}!
   users:
+    follow_limit_reached: Ùn pidete seguità più di %{limit} conti
     invalid_email: L’indirizzu e-mail ùn hè currettu
     invalid_otp_token: U codice d’identificazione ùn hè currettu
     otp_lost_help_html: S’è voi avete persu i dui, pudete cuntattà %{email}
     seamless_external_login: Site cunnettatu·a dapoi un serviziu esternu, allora i parametri di chjave d’accessu è d’indirizzu e-mail ùn so micca dispunibili.
     signed_in_as: 'Cunnettatu·a cum’è:'
+  verification:
+    explanation_html: 'Pudete <strong>verificavi cum''è u pruprietariu di i ligami in i metadati di u vostru prufile</strong>. Per quessa, u vostru situ deve avè un ligame versu a vostra pagina Mastodon. U ligame <strong>deve</strong> avè un''attributu <code>rel="me"</code>. U cuntenutu di u testu di u ligame ùn hè micca impurtante. Eccu un''esempiu:'
+    verification: Verificazione
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index 7b6021f13c61904ceffc8bf0ccb570753ea4f8e9..424ec3dab65fa0a4f14bf76b68506dfb7e34a3ca 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -1,44 +1,1016 @@
 ---
 cs:
   about:
-    about_hashtag_html: Toto jsou veřejné příspěvky typu označené jako <strong>#%{hashtag}</strong>. Pokud máte účet kdekoliv na fediverse, 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 decentrovalizovaná jako e-mail.
+    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_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: 'Server spravuje:'
-    closed_registrations: Registrace na této instanci jsou momentálně uzavřené. Můžete si však najít jinou instanci, vytvořit si na ní účet a získat z ní přístup do naprosto stejné sítě.
+    administered_by: 'Instanci 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ě.
     contact: Kontakt
     contact_missing: Nenastaveno
     contact_unavailable: Neuvedeno
-    description_headline: Co je %{domain}?
-    domain_count_after: dalším instancím
-    domain_count_before: Připojeno k
+    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, poučen z chyb jiných sociálních sítí, se snaží bojovat se zneužíváním sociálních sítí vytvářením etických možností.
+      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_title: Jste osoba, ne produkt.
-    generic_description: "%{domain} je jedním serverem v síti"
+      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
+    generic_description: "%{domain} je jedním ze serverů v síti"
+    hosted_on: Instance Mastodon na adrese %{domain}
     learn_more: Zjistit více
+    other_instances: Seznam instancí
+    privacy_policy: Zásady soukromí
     source_code: Zdrojový kód
-    status_count_after: příspěvků
-    status_count_before: Kdo je autorem
-    user_count_after: uživatelů
-    user_count_before: Domov pro
+    status_count_after:
+      few: příspěvky
+      one: příspěvek
+      other: příspěvků
+    status_count_before: Kteří napsali
+    terms: Podmínky používání
+    user_count_after:
+      few: uživatelů
+      one: uživatele
+      other: uživatelů
+    user_count_before: Domov
     what_is_mastodon: Co je Mastodon?
   accounts:
+    choices_html: 'Volby uživatele %{name}:'
     follow: Sledovat
-    followers: Sledovatelé
-    following: Sleduje
+    followers:
+      few: Sledovatelé
+      one: Sledovatel
+      other: Sledovatelů
+    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}:'
     network_hidden: Tato informace není k dispozici
     nothing_here: Tady nic není!
+    people_followed_by: Lidé, které sleduje %{name}
+    people_who_follow: Lidé, kteří sledují uživatele %{name}
+    pin_errors:
+      following: Musíte již sledovat osobu, kterou chcete podpořit
+    posts:
+      few: Tooty
+      one: Toot
+      other: Tootů
+    posts_tab_heading: Tooty
+    posts_with_replies: Tooty a odpovědi
+    reserved_username: Toto uživatelské jméno je rezervováno
+    roles:
+      admin: Administrátor
+      bot: Robot
+      moderator: Moderátor
+    unfollow: Přestat sledovat
+  admin:
+    account_actions:
+      action: Vykonat akci
+      title: Vykonat moderační akci pro účet %{acct}
+    account_moderation_notes:
+      create: Zanechat poznámku
+      created_msg: Poznámka moderátora byla úspěšně vytvořena!
+      delete: Smazat
+      destroyed_msg: Poznámka moderátora byla úspěšně zničena!
+    accounts:
+      are_you_sure: Jste si jistý/á?
+      avatar: Avatar
+      by_domain: Doména
+      change_email:
+        changed_msg: E-mail k tomuto účtu byl úspěšně změněn!
+        current_email: Současný e-mail
+        label: Změnit e-mail
+        new_email: Nový e-mail
+        submit: Změnit e-mail
+        title: Změnit e-mail uživateli %{username}
+      confirm: Potvrdit
+      confirmed: Potvrzeno
+      confirming: Potvrzuji
+      deleted: Smazáno
+      demote: Degradovat
+      disable: Zablokovat
+      disable_two_factor_authentication: Zakázat 2FA
+      disabled: Blokováno
+      display_name: Zobrazované jméno
+      domain: Doména
+      edit: Upravit
+      email: E-mail
+      email_status: Stav e-mailu
+      enable: Povolit
+      enabled: Povoleno
+      feed_url: URL proudu
+      followers: Sledovatelé
+      followers_url: URL sledovatelů
+      follows: Sledovaní
+      header: Hlavička
+      inbox_url: URL přijatých zpráv
+      invited_by: Pozván/a uživatelem
+      ip: IP
+      joined: Připojil/a se
+      location:
+        all: Vše
+        local: Místní
+        remote: Vzdálené
+        title: Umístění
+      login_status: Stav přihlášení
+      media_attachments: Mediální přílohy
+      memorialize: Změnit na „in memoriam“
+      moderation:
+        active: Aktivní
+        all: Vše
+        silenced: Utišen/a
+        suspended: Pozastaven/a
+        title: Moderace
+      moderation_notes: Moderační poznámky
+      most_recent_activity: Nejnovější aktivita
+      most_recent_ip: Nejnovější IP
+      no_limits_imposed: Nejsou nastavena žádná omezení
+      not_subscribed: Neodebírá
+      outbox_url: URL odchozích zpráv
+      perform_full_suspension: Pozastavit
+      profile_url: URL profilu
+      promote: Povýšit
+      protocol: Protokol
+      public: Veřejný
+      push_subscription_expires: Odebírání PuSH expiruje
+      redownload: Obnovit profil
+      remove_avatar: Odstranit avatar
+      remove_header: Odstranit hlavičku
+      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_password: Obnovit heslo
+      resubscribe: Znovu odebírat
+      role: Oprávnění
+      roles:
+        admin: Administrátor
+        moderator: Moderátor
+        staff: Personál
+        user: Uživatel
+      salmon_url: URL Salmon
+      search: Hledat
+      shared_inbox_url: URL sdílených přijatých zpráv
+      show:
+        created_reports: Vytvořená nahlášení
+        targeted_reports: Nahlášeni ostatními
+      silence: Utišit
+      silenced: Utišen/a
+      statuses: Příspěvky
+      subscribe: Odebírat
+      suspended: Pozastaven/a
+      title: Účty
+      unconfirmed_email: Nepotvrzený e-mail
+      undo_silenced: Zrušit utišení
+      undo_suspension: Zrušit pozastavení
+      unsubscribe: Přestat odebírat
+      username: Uživatelské jméno
+      warn: Varovat
+      web: Web
+    action_logs:
+      actions:
+        assigned_to_self_report: "%{name} přidělil/a hlášení %{target} sobě"
+        change_email_user: "%{name} změnil/a e-mailovou adresu uživatele %{target}"
+        confirm_user: "%{name} potvrdil/a e-mailovou adresu uživatele %{target}"
+        create_account_warning: "%{name} poslal/a varování uživateli %{target}"
+        create_custom_emoji: "%{name} nahrál/a nové emoji %{target}"
+        create_domain_block: "%{name} zablokoval/a doménu %{target}"
+        create_email_domain_block: "%{name} přidal/a e-mailovou doménu %{target} na černou listinu"
+        demote_user: "%{name} degradoval/a uživatele %{target}"
+        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}"
+        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}"
+        enable_user: "%{name} povolil/a přihlašování pro uživatele %{target}"
+        memorialize_account: "%{name} změnil/a účet %{target} na stránku „in memoriam“"
+        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}"
+        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}"
+        unassigned_report: "%{name} odebral/a nahlášení %{target}"
+        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)"
+      title: Záznam auditu
+    custom_emojis:
+      by_domain: Doména
+      copied_msg: Místní kopie emoji byla úspěšně vytvořena
+      copy: Kopírovat
+      copy_failed_msg: Nebylo možné vytvořit místní kopii tohoto emoji
+      created_msg: Emoji úspěšně vytvořeno!
+      delete: Smazat
+      destroyed_msg: Emoji úspěšně zničeno!
+      disable: Zakázat
+      disabled_msg: Emoji bylo úspěšně zakázáno
+      emoji: Emoji
+      enable: Povolit
+      enabled_msg: Emoji bylo úspěšně povoleno
+      image_hint: PNG až do 50KB
+      listed: Uvedené
+      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é
+      update_failed_msg: Nebylo možné aktualizovat toto emoji
+      updated_msg: Emoji úspěšně aktualizováno!
+      upload: Nahrát
+    dashboard:
+      backlog: opožděné úlohy
+      config: Konfigurace
+      feature_deletions: Smazání účtů
+      feature_invites: Odkazy pozvánek
+      feature_profile_directory: Adresář profilů
+      feature_registrations: Registrace
+      feature_relay: Federovací most
+      features: Vlastnosti
+      hidden_service: Federace se skrytými službami
+      open_reports: otevřená hlášení
+      recent_users: Nedávní uživatelé
+      search: Fulltextové vyhledávání
+      single_user_mode: Režim jednoho uživatele
+      software: Software
+      space: Využití prostoru
+      title: Přehled
+      total_users: uživatelů celkem
+      trends: Trendy
+      week_interactions: interakcí tento týden
+      week_users_active: aktivních tento týden
+      week_users_new: uživatelů tento týden
+    domain_blocks:
+      add_new: Přidat novou blokaci domény
+      created_msg: Blokace domény se právě vyřizuje
+      destroyed_msg: Blokace domény byla zrušena
+      domain: Doména
+      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.
+        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é
+          silence: Utišit
+          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_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é
+      show:
+        affected_accounts:
+          few: "%{count} účty v databázi byly ovlivněny"
+          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
+        title: Zrušit blokaci domény %{domain}
+        undo: Odvolat
+      undo: Odvolat blokaci domény
+    email_domain_blocks:
+      add_new: Přidat nový
+      created_msg: E-mailová doména úspěšně přidána na černou listinu
+      delete: Smazat
+      destroyed_msg: E-mailová doména úspěšně odstraněna z černé listiny
+      domain: Doména
+      new:
+        create: Přidat doménu
+        title: Nový e-mail pro zablokování
+      title: Černá listina e-mailů
+    followers:
+      back_to_account: Zpět na účet
+      title: Sledovatelé uživatele %{acct}
+    instances:
+      delivery_available: Doručení je k dispozici
+      known_accounts:
+        few: "%{count} známé účty"
+        one: "%{count} známý účet"
+        other: "%{count} známých účtů"
+      moderation:
+        all: Vše
+        limited: Omezené
+        title: Moderace
+      title: Federace
+      total_blocked_by_us: Blokované námi
+      total_followed_by_them: Sledované jím
+      total_followed_by_us: Sledované námi
+      total_reported: Nahlášení o něm
+      total_storage: Mediální přílohy
+    invites:
+      deactivate_all: Deaktivovat vše
+      filter:
+        all: Vše
+        available: Dostupné
+        expired: Vypršelé
+        title: Filtrovat
+      title: Pozvánky
+    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."
+      disable: Zakázat
+      disabled: Zakázáno
+      enable: Povolit
+      enable_hint: Je-li tohle povoleno, začne váš server odebírat všechny veřejné tooty z tohoto mostu a odesílat na něj své vlastní veřejné tooty.
+      enabled: Povoleno
+      inbox_url: URL mostu
+      pending: Čekám na souhlas mostu
+      save_and_enable: Uložit a povolit
+      setup: Nastavit připojení k mostu
+      status: Stav
+      title: Mosty
+    report_notes:
+      created_msg: Poznámka o nahlášení úspěšně vytvořena!
+      destroyed_msg: Poznámka o nahlášení úspěšně smazána!
+    reports:
+      account:
+        note: poznámka
+        report: nahlášení
+      action_taken_by: Akci vykonal/a
+      are_you_sure: Jste si jistý/á?
+      assign_to_self: Přidělit ke mně
+      assigned: Přiřazený moderátor
+      comment:
+        none: Žádné
+      created_at: Nahlášené
+      mark_as_resolved: Označit jako vyřešené
+      mark_as_unresolved: Označit jako nevyřešené
+      notes:
+        create: Přidat poznámku
+        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...
+      reopen: Znovu otevřít nahlášení
+      report: 'Nahlásit #%{id}'
+      reported_account: Nahlášený účet
+      reported_by: Nahlášeno uživatelem
+      resolved: Vyřešeno
+      resolved_msg: Nahlášení úspěšně vyřešeno!
+      status: Stav
+      title: Nahlášení
+      unassign: Odebrat
+      unresolved: Nevyřešeno
+      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
+        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.
+        title: Výchozí sledovaní pro nové uživatele
+      contact_information:
+        email: Pracovní e-mail
+        username: Uživatelské jméno kontaktu
+      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
+        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í
+      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
+      profile_directory:
+        desc_html: Dovolit uživatelům být objevitelní
+        title: Povolit adresář profilů
+      registrations:
+        closed_message:
+          desc_html: Zobrazí se na hlavní stránce, jsou-li registrace uzavřeny. Můžete použít i HTML značky
+          title: Zpráva o uzavřených registracích
+        deletion:
+          desc_html: Dovolit každému smazání svého účtu
+          title: Zpřístupnit smazání účtu
+        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
+      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
+      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
+      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
+      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
+      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
+      thumbnail:
+        desc_html: Používáno pro náhledy přes OpenGraph a API. Doporučuje se rozlišení 1200x630px
+        title: Miniatura instance
+      timeline_preview:
+        desc_html: Zobrazit na hlavní straně veřejnou časovou osu
+        title: Náhled časové osy
+      title: Nastavení stránky
+    statuses:
+      back_to_account: Zpět na stránku účtu
+      batch:
+        delete: Vymazat
+        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
+      with_media: S médii
+    subscriptions:
+      callback_url: Zpáteční URL
+      confirmed: Potvrzeno
+      expires_in: Vyprší v
+      last_delivery: Poslední doručení
+      title: WebSub
+      topic: Téma
+    tags:
+      accounts: Účty
+      hidden: Skryté
+      hide: Skrýt z adresáře
+      name: Hashtag
+      title: Hashtagy
+      unhide: Zobrazit v adresáři
+      visible: Viditelné
+    title: Administrace
+    warning_presets:
+      add_new: Přidat nové
+      delete: Smazat
+      edit: Upravit
+      edit_preset: Upravit přednastavení pro varování
+      title: Spravovat přednastavení pro varování
+  admin_mailer:
+    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})
+  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
+  applications:
+    created: Aplikace úspěšně vytvořena
+    destroyed: Aplikace úspěšně smazána
+    invalid_url: Zadaná adresa URL je neplatná
+    regenerate_token: Znovu vygenerovat přístupový token
+    token_regenerated: Přístupový token byl úspěšně vygenerován
+    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>.
+    change_password: Heslo
+    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ý.
+    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
+    resend_confirmation: Znovu odeslat pokyny pro potvrzení
+    reset_password: Obnovit heslo
+    security: Zabezpečení
+    set_new_password: Nastavit nové heslo
+  authorize_follow:
+    already_following: Tento účet již sledujete
+    error: Při hledání vzdáleného účtu bohužel nastala chyba
+    follow: Sledovat
+    follow_request: 'Poslal/a jste požadavek o sledování uživateli:'
+    following: 'Podařilo se! Nyní sledujete uživatele:'
+    post_follow:
+      close: Nebo můžete toto okno klidně zavřít.
+      return: Zobrazit profil uživatele
+      web: Přejít na web
+    title: Sledovat uživatele %{acct}
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count} hod"
+      about_x_months: "%{count} měsíců"
+      about_x_years: "%{count} let"
+      almost_x_years: "%{count} let"
+      half_a_minute: Právě teď
+      less_than_x_minutes: "%{count} min"
+      less_than_x_seconds: Právě teď
+      over_x_years: "%{count} let"
+      x_days: "%{count} dní"
+      x_minutes: "%{count} min"
+      x_months: "%{count} mesíců"
+      x_seconds: "%{count} s"
+  deletes:
+    bad_password_msg: Dobrý pokus, hackeři! Nesprávné heslo
+    confirm_password: Zadejte svoje současné heslo pro ověření vaší identity
+    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_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í.
+    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é"
+      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.
+    '422':
+      content: Bezpečnostní ověření selhalo. Neblokujete cookoes?
+      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.
+      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.
+  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...
+      request: Vyžádat svůj archiv
+      size: Velikost
+    blocks: Blokujete
+    csv: CSV
+    domain_blocks: Blokace domén
+    follows: Sledujete
+    lists: Seznamy
+    mutes: Ignorujete
+    storage: Paměť médií
+  filters:
+    contexts:
+      home: Domovská časová osa
+      notifications: Oznámení
+      public: Veřejný časové osy
+      thread: Konverzace
+    edit:
+      title: Upravit filtr
+    errors:
+      invalid_context: Nebylo poskytnuto nic, nebo má neplatný kontext
+      invalid_irreversible: Nezvratné filtrování funguje pouze v souvislosti s domovskou osou či oznámeními
+    index:
+      delete: Smazat
+      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:
+    changes_saved_msg: Změny byly úspěšně uloženy!
+    copy: Kopírovat
+    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
+      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
+  imports:
+    preface: Můžete importovat data, která jste exportoval/a z jiné instance, 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
+      following: Seznam sledovaných
+      muting: Seznam ignorovaných
+    upload: Nahrát
+  in_memoriam_html: Navždy budeme vzpomínat.
+  invites:
+    delete: Deaktivovat
+    expired: Vypršelé
+    expires_in:
+      '1800': 30 minut
+      '21600': 6 hodin
+      '3600': 1 hodina
+      '43200': 12 hodin
+      '604800': 1 týden
+      '86400': 1 den
+    expires_in_prompt: Nikdy
+    generate: Vygenerovat
+    invited_by: 'Byl/a jste pozván/a uživatelem:'
+    max_uses:
+      few: "%{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
+    table:
+      expires_at: Vyprší
+      uses: Použití
+    title: Pozvěte 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
+      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!
+  moderation:
+    title: Moderace
+  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é!
+      subject:
+        few: "%{count} nová 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...
+    favourite:
+      body: 'Váš příspěvek si oblíbil/a %{name}:'
+      subject: "%{name} si oblíbil/a váš příspěvek"
+      title: Nové oblíbení
+    follow:
+      body: "%{name} vás nyní sleduje!"
+      subject: "%{name} vás nyní sleduje"
+      title: Nový sledovatel
+    follow_request:
+      action: Spravovat požadavky o sledování
+      body: "%{name} požádal/a o povolení vás sledovat"
+      subject: 'Čekající sledovatel: %{name}'
+      title: Nový požadavek o sledování
+    mention:
+      action: Odpovědět
+      body: 'Byl/a jste zmíněn/a uživatelem %{name} v:'
+      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í
+  number:
+    human:
+      decimal_units:
+        format: "%n %u"
+        units:
+          billion: mld
+          million: mil
+          quadrillion: bld
+          thousand: tis
+          trillion: bil
+  pagination:
+    newer: Novější
+    next: Další
+    older: Starší
+    prev: Před
+    truncate: "&hellip;"
+  preferences:
+    languages: Jazyky
+    other: Ostatní
+    publishing: Publikování
+    web: Web
+  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
+    no_account_html: Ještě nemáte účet? Můžete se <a href='%{sign_up_path}' target='_blank'>registrovat zde</a>
+    proceed: Pokračovat ke sledování
+    prompt: 'Budete sledovat:'
+    reason_html: "<strong>Proč je tento krok nutný?</strong> <code>%{instance}</code> nemusí být serverem, na kterém jste registrován/a, proto vás musíme nejdříve přesměrovat na váš domovský server."
+  remote_interaction:
+    favourite:
+      proceed: Pokračovat k oblíbení
+      prompt: 'Chcete si oblíbit tento toot:'
+    reblog:
+      proceed: Pokračovat k boostnutí
+      prompt: 'Chcete boostnout tento toot:'
+    reply:
+      proceed: Pokračovat k odpovězení
+      prompt: 'Chcete odpovědět na tento toot:'
+  remote_unfollow:
+    error: Chyba
+    title: Nadpis
+    unfollowed: Už nesledujete
+  scheduled_statuses:
+    over_daily_limit: Překročil/a jste limit %{limit} plánovaných tootů pro tento den
+    over_total_limit: Překročil/a jste limit %{limit} plánovaných tootů
+    too_soon: Plánované datum musí být v budoucnosti
+  sessions:
+    activity: Nejnovější aktivita
+    browser: Prohlížeč
+    browsers:
+      alipay: Alipay
+      blackberry: Blackberry
+      chrome: Chrome
+      edge: Microsoft Edge
+      electron: Electron
+      firefox: Firefox
+      generic: Neznámý prohlížeč
+      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: 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
+    platforms:
+      adobe_air: Adobe Air
+      android: Android
+      blackberry: Blackberry
+      chrome_os: Chrome OS
+      firefox_os: Firefox OS
+      ios: iOS
+      linux: Linux
+      mac: Mac
+      other: neznámé platformě
+      windows: Windows
+      windows_mobile: Windows Mobile
+      windows_phone: Windows Phone
+    revoke: Zamítnout
+    revoke_success: Relace úspěšně zamítnuta
+    title: Relace
+  settings:
+    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é
+    import: Import
+    migrate: Přesunutí účtu
+    notifications: Oznámení
+    preferences: Předvolby
+    settings: Nastavení
+    two_factor_authentication: Dvoufaktorové ověřování
+    your_apps: Vaše aplikace
+  statuses:
+    attached:
+      description: 'Přiloženo: %{attached}'
+      image:
+        few: "%{count} obrázky"
+        one: "%{count} obrázek"
+        other: "%{count} obrázků"
+      video:
+        few: "%{count} videa"
+        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}'
+      one: 'obsahoval nepovolený hashtag: %{tags}'
+      other: 'obsahoval nepovolené hashtagy: %{tags}'
+    language_detection: Zjistit jazyk automaticky
+    open_in_web: Otevřít na webu
+    over_character_limit: limit %{max} znaků byl překročen
+    pin_errors:
+      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í
+    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
+      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
+  stream_entries:
+    pinned: Připnutý toot
+    reblogged: boostnul/a
+    sensitive_content: Citlivý obsah
+  terms:
+    body_html: |
+      <h2>Zásady soukromí</h2>
+      <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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Na co používáme vaše informace?</h3>
+
+      <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>
+      </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>
+
+      <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>
+
+      <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>
+      </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 můžete nenávratně smazat váš účet.</p>
+
+      <hr class="spacer"/>
+
+      <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>Používáme cookies pro pochopení a ukládání vašich předvoleb pro budoucí návštěvy.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Zveřejňujeme jakékoliv informace třetím stranám?</h3>
+
+      <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>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>
+
+      <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 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>
+
+      <p>Právní požadavky mohou být jiné, pokud se tento server nachází v jiné jurisdikci.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Změny v našich zásadách soukromí</h3>
+
+      <p>Rozhodneme-li se naše zásady soukromí změnit, zveřejníme tyto změny na této stránce.</p>
+
+      <p>Tento dokument je dostupný pod licencí CC-BY-SA. Byl naposledy aktualizován 7. března 2018.</p>
+
+      <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
+    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.
+    disable: Zakázat
+    enable: Povolit
+    enabled: Dvoufaktorové ověřování je povoleno
+    enabled_success: Dvoufaktorové 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_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ý?
   user_mailer:
+    backup_ready:
+      explanation: Vyžádal/a jste si úplnou zálohu svého účtu Mastodon. Nyní je připravena ke stažení!
+      subject: Váš archiv je připraven ke stažení
+      title: Stažení archivu
+    warning:
+      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.
+      review_server_policies: Posoudit politiku serveru
+      subject:
+        disable: Váš účet %{acct} byl zmražen
+        none: Varování pro uživatele %{acct}
+        silence: Váš účet %{acct} byl omezen
+        suspend: Váš účet %{acct} byl pozastaven
+      title:
+        disable: Účet zmražen
+        none: Varování
+        silence: Účet omezen
+        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.
+      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.'
+      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.
+      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_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
+    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:'
+  verification:
+    explanation_html: 'Můžete se <strong>ověřit jako vlastník odkazů v metadatech profilu</strong>. Pro tento účel musí stránka v odkazu obsahovat odkaz zpět na váš profil na Mastodonu. Odkaz zpět <strong>musí</strong> mít atribut <code>rel="me"</code>. Na textu odkazu nezáleží. Zde je příklad:'
+    verification: Ověření
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..53b474c167f62ebbdbfbefd29fe9e6e3bca8c6f1
--- /dev/null
+++ b/config/locales/cy.yml
@@ -0,0 +1,935 @@
+---
+cy:
+  about:
+    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
+    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.
+    contact: Cyswllt
+    contact_missing: Heb ei osod
+    contact_unavailable: Ddim yn berthnasol
+    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
+    generic_description: Mae %{domain} yn un gweinydd yn y rhwydwaith
+    hosted_on: Mastodon wedi ei weinyddu ar %{domain}
+    learn_more: Dysu mwy
+    other_instances: Rhestr achosion
+    privacy_policy: Polisi preifatrwydd
+    source_code: Cod ffynhonnell
+    status_count_after:
+      few: statwsau
+      many: statwsau
+      one: statws
+      other: statwsau
+      two: statwsau
+      zero: statwsau
+    status_count_before: Ysgriffennwyd gan
+    terms: Telerau gwasanaeth
+    user_count_after:
+      few: defnyddwyr
+      many: defnyddwyr
+      one: defnyddiwr
+      other: defnyddwyr
+      two: defnyddwyr
+      zero: defnyddwyr
+    user_count_before: Cartref i
+    what_is_mastodon: Beth yw Mastodon?
+  accounts:
+    choices_html: 'Dewisiadau %{name}:'
+    follow: Dilynwch
+    followers:
+      few: Dilynwyr
+      many: Dilynwyr
+      one: Dilynwr
+      other: Dilynwyr
+      two: Dilynwyr
+      zero: Dilynwyr
+    following: Yn dilyn
+    joined: Ymunodd %{date}
+    link_verified_on: Gwiriwyd perchnogaeth y ddolen yma ar %{date}
+    media: Cyfryngau
+    moved_html: 'Mae %{name} wedi symud i %{new_profile_link}:'
+    network_hidden: Nid yw'r wybodaeth hyn ar gael
+    nothing_here: Does dim byd yma!
+    people_followed_by: Pobl y mae %{name} yn ei ddilyn
+    people_who_follow: Pobl sy'n dilyn %{name}
+    pin_errors:
+      following: Rhaid i ti fod yn dilyn y person yr ydych am ei gymeradwyo yn barod
+    posts:
+      few: Tŵtiau
+      many: Tŵtiau
+      one: Tŵt
+      other: Tŵtiau
+      two: Tŵtiau
+      zero: Tŵtiau
+    posts_tab_heading: Tŵtiau
+    posts_with_replies: Tŵtiau ac atebion
+    reserved_username: Mae'r enw defnyddiwr ar gadw
+    roles:
+      admin: Gweinyddwr
+      bot: Bot
+      moderator: Safonwr
+    unfollow: Dad-ddilyn
+  admin:
+    account_actions:
+      action: Cyflawni gweithred
+    account_moderation_notes:
+      create: Gadael nodyn
+      created_msg: Crewyd nodyn cymedroli yn llwyddiannus!
+      delete: Dileu
+      destroyed_msg: Dinistrwyd nodyn cymedroli yn llwyddiannus!
+    accounts:
+      are_you_sure: Ydych chi'n siŵr?
+      avatar: Afatar
+      by_domain: Parth
+      change_email:
+        changed_msg: E-bost cyfrif wedi ei newid yn llwyddiannus!
+        current_email: E-bost Cyfredol
+        label: Newid E-bost
+        new_email: E-bost Newydd
+        submit: Newid E-bost
+        title: Newid E-bost i %{username}
+      confirm: Cadarnhau
+      confirmed: Cadarnhawyd
+      confirming: Cadarnhau
+      deleted: Wedi dileu
+      demote: Diraddio
+      disable: Diffodd
+      disable_two_factor_authentication: Diffodd 2FA
+      disabled: Wedi ei ddiffodd
+      display_name: Enw arddangos
+      domain: Parth
+      edit: Golygu
+      email: E-bost
+      email_status: Statws E-bost
+      enable: Galluogi
+      enabled: Wedi ei alluogi
+      feed_url: Ffrwd URL
+      followers: Dilynwyr
+      followers_url: URL Dilynwyr
+      follows: Yn dilyn
+      header: Pennawd
+      inbox_url: URL Mewnflwch
+      invited_by: Gwahoddwyd gan
+      ip: IP
+      joined: Ymunodd
+      location:
+        all: Popeth
+        local: Lleol
+        remote: Pell
+        title: Lleoliad
+      login_status: Statws mewngofnodi
+      media_attachments: Atodiadau
+      memorialize: Troi yn gofeb
+      moderation:
+        active: Yn weithredol
+        all: Popeth
+        silenced: Wedi ei dawelu
+        suspended: Wedi ei atal
+        title: Cymedroli
+      moderation_notes: Nodiadau cymedroli
+      most_recent_activity: Gweithgarwch diweddaraf
+      most_recent_ip: IP diweddaraf
+      no_limits_imposed: Dim terfynau wedi'i gosod
+      not_subscribed: Heb danysgrifio
+      outbox_url: Allflwch URL
+      perform_full_suspension: Atal
+      profile_url: URL proffil
+      promote: Hyrwyddo
+      protocol: Protocol
+      public: Cyhoeddus
+      push_subscription_expires: Tanysgrifiad PuSH yn dod i ben
+      redownload: Adnewyddu proffil
+      remove_avatar: Dileu afatar
+      resend_confirmation:
+        already_confirmed: Mae'r defnyddiwr hwn wedi ei gadarnhau yn barod
+        send: Ailanfonwch e-bost cadarnhad
+        success: E-bost cadarnhau wedi ei anfon yn llwyddiannus!
+      reset: Ailosod
+      reset_password: Ailosod cyfrinair
+      resubscribe: Aildanysgrifio
+      role: Caniatâd
+      roles:
+        admin: Gweinyddwr
+        moderator: Safonwr
+        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
+      silence: Tawelu
+      silenced: Tawelwyd
+      statuses: Statysau
+      subscribe: Tanysgrifio
+      suspended: Ataliwyd
+      title: Cyfrifon
+      unconfirmed_email: E-bost heb ei gadarnhau
+      undo_silenced: Dadwneud tawelu
+      undo_suspension: Dadwneud ataliad
+      unsubscribe: Dad-danysgrifio
+      username: Enw defnyddiwr
+      warn: Rhybuddio
+      web: Gwe
+    action_logs:
+      actions:
+        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_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}
+        demote_user: Diraddiodd %{name} y defnyddiwr %{target}
+        destroy_custom_emoji: Dinistriodd %{name} emoji %{target}
+        destroy_domain_block: Dadflociodd %{name} y parth %{target}
+        destroy_email_domain_block: Gwynrestrodd %{name} parth e-bost %{target}
+        destroy_status: Cafodd %{name} wared ar statws gan %{target}
+        disable_2fa_user: Diffoddodd %{name} ar ofyniad dau gam ar gyfer y defnyddiwr %{target}
+        disable_custom_emoji: Diffoddodd %{name} emoji %{target}
+        disable_user: Diffoddodd %{name} mewngofnodi ar gyfer y defnyddiwr %{target}
+        enable_custom_emoji: Galluogodd %{name} emoji %{target}
+        enable_user: Galluogodd %{name} mewngofnodi ar gyfer y defnyddiwr %{target}
+        memorialize_account: Newidodd %{name} gyfrif %{target} i dudalen goffau
+        promote_user: Dyrchafodd %{name} y defnyddiwr %{target}
+        remove_avatar_user: Cafodd %{name} wared ar afatar %{target}
+        reopen_report: Ailagorodd %{name} adroddiad %{target}
+        reset_password_user: Ailosododd %{name} gyfrinair y defnyddiwr %{target}
+        resolve_report: Datrusodd %{name} adroddiad %{target}
+        silence_account: Tawelodd %{name} gyfrif %{target}
+        suspend_account: Ataliodd %{name} gyfrif %{target}
+        unassigned_report: Dadbenododd %{name} adroddiad %{target}
+        unsilence_account: Terfynodd %{name} dawelu cyfrif %{target}
+        unsuspend_account: Terfynodd %{name} yr ataliad ar gyfrif %{target}
+        update_custom_emoji: Diweddarodd %{name} emoji %{target}
+        update_status: Diweddarodd %{name} statws gan %{target}
+      deleted_status: "(statws wedi ei ddileu)"
+      title: Log archwilio
+    custom_emojis:
+      by_domain: Parth
+      copied_msg: Llwyddwyd i greu copi lleol o'r emoji
+      copy: Copïo
+      copy_failed_msg: Methwyd i greu copi lleol o'r emoji hwnnw
+      created_msg: Llwyddwyd i greu emoji!
+      delete: Dileu
+      destroyed_msg: Llwyddwyd i ddinistrio emojo!
+      disable: Diffodd
+      disabled_msg: Llwyddwyd i ddiffodd yr emoji hwnnw
+      emoji: Emoji
+      enable: Galluogi
+      enabled_msg: Llwyddwyd i alluogi yr emoji hwnnw
+      image_hint: PNG hyd at 50KB
+      listed: Rhestredig
+      new:
+        title: Ychwanegu emoji personol newydd
+      overwrite: Trosysgrifio
+      shortcode: Byrgod
+      shortcode_hint: O leiaf 2 nodyn, dim ond nodau alffaniwmerig a tanlinellau
+      title: Emoji unigryw
+      unlisted: Heb eu rhestru
+      update_failed_msg: Methwyd a diweddaru'r emoji hwnnw
+      updated_msg: Llwyddwyd i ddiweddaru'r emoji!
+      upload: Uwchlwytho
+    dashboard:
+      backlog: tasgau heb eu cwblhau
+      config: Cyfluniad
+      feature_deletions: Dileadau cyfrif
+      feature_invites: Dolenni gwahodd
+      feature_registrations: Cofrestriadau
+      feature_relay: Relái ffederasiwn
+      features: Nodweddion
+      hidden_service: Ffederasiwn a gwasanaethau cudd
+      open_reports: adroddiadau agored
+      recent_users: Defnyddwyr diweddar
+      search: Chwilio testun llawn
+      single_user_mode: Modd un defnyddiwr
+      software: Meddalwedd
+      space: Defnydd o ofod
+      title: Dangosfwrdd
+      total_users: cyfanswm defnyddwyr
+      trends: Tueddiadau
+      week_interactions: ymadweithiau yr wythnos hon
+      week_users_active: gweithredol yr wythnos hon
+      week_users_new: defnyddwyr yr wythnos hon
+    domain_blocks:
+      add_new: Ychwanegu
+      created_msg: Mae'r bloc parth nawr yn cael ei brosesu
+      destroyed_msg: Mae'r bloc parth wedi ei ddadwneud
+      domain: Parth
+      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.
+        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
+          silence: Tawelwch
+          suspend: Atal
+        title: Blocio parth newydd
+      reject_media: Gwrthod dogfennau cyfryngau
+      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
+      show:
+        affected_accounts: "%{count} o gyfrifoedd yn y bas data wedi eu hefeithio"
+        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
+    email_domain_blocks:
+      add_new: Ychwanegu
+      created_msg: Llwyddwyd i ychwanegu parth e-bost i'r gosbrestr
+      delete: Dileu
+      destroyed_msg: Llwyddwyd i ddileu parth e-bost o'r gosbrestr
+      domain: Parth
+      new:
+        create: Ychwanegu parth
+        title: Cofnod newydd yng nghosbrestr e-byst
+      title: Cosbrestr e-bost
+    instances:
+      moderation:
+        all: Pob
+        limited: Gyfyngedig
+      title: Ffederasiwn
+    invites:
+      deactivate_all: Diffodd pob un
+      filter:
+        all: Pob
+        available: Ar gael
+        expired: Wedi dod i ben
+        title: Hidlo
+      title: Gwahoddiadau
+    relays:
+      add_new: Ychwanegau relái newydd
+      delete: Dileu
+      description_html: Mae <strong>relái ffederasiwn</strong> yn weinydd ganol sy'n cyfnewid niferoedd ucheol o dŵtiau cyhoeddus rhwng gweinyddwyr sydd wedi tanysgrifio ac yn cyhoeddi iddo. <strong>Gall helpu weinyddwyr bach a cymhedrol eu maint i ddarganfod cynnwys o'r ffedysawd</strong>, fel arall bydd gofyn ara ddefnyddwyr lleol yn dilyn unigolion ar weinyddwyr eraill a llaw.
+      disable: Diffodd
+      disabled: Wedi'i ddiffodd
+      enable: Galluogi
+      enable_hint: Unwaith y bydd wedi ei alluogi, bydd eich gweinydd yn tanysgrifio i holl dŵtiau cyhoeddus o'r relai hwn, ac yn dechrau anfon tŵtiau y gweinydd hwn ato.
+      enabled: Wedi ei alluogi
+      inbox_url: URL relái
+      pending: Aros am gymeradywaeth i'r relái
+      save_and_enable: Cadw a galluogi
+      setup: Sefydlu cysylltiad relái
+      status: Statws
+      title: Cyfnewidwyr
+    report_notes:
+      created_msg: Llwyddwyd i greu nodyn adroddiad!
+      destroyed_msg: Llwyddwyd i ddileu nodyn adroddiad!
+    reports:
+      account:
+        note: nodyn
+        report: adroddiad
+      action_taken_by: Gwnaethpwyd hyn gan
+      are_you_sure: Ydych chi'n sicr?
+      assign_to_self: Aseinio i mi
+      assigned: Cymedrolwr wedi'i aseinio
+      comment:
+        none: Dim
+      created_at: Adroddwyd
+      mark_as_resolved: Nodi fel wedi'i ddatrys
+      mark_as_unresolved: Nodi fel heb ei ddatrys
+      notes:
+        create: Ychwanegu nodyn
+        create_and_resolve: Datrys gyda nodyn
+        create_and_unresolve: Ailagor gyda nodyn
+        delete: Dileu
+        placeholder: Disgrifiwch pa weithredoedd sydd wedi eu cymryd, neu unrhyw ddiweddariadau eraill...
+      reopen: Ailagor adroddiad
+      report: 'Adroddiad #%{id}'
+      reported_account: Cyfrif wedi ei adrodd
+      reported_by: Adroddwyd gan
+      resolved: Wedi ei ddatrys
+      resolved_msg: Llwyddwyd i ddatrys yr adroddiad!
+      status: Statws
+      title: Adroddiadau
+      unassign: Dadneilltuo
+      unresolved: Heb ei ddatrys
+      updated_at: Diweddarwyd
+    settings:
+      activity_api_enabled:
+        desc_html: Niferoedd o statysau wedi eu postio'n lleol, defnyddwyr gweithredol, a cofrestradau newydd mewn bwcedi wythnosol
+        title: Cyhoeddi ystatedgau cyfangronedig am weithgaredd defnyddwyr
+      bootstrap_timeline_accounts:
+        desc_html: Gwahanu sawl enw defnyddiwr a coma. Dim ond cyfrifoedd lleol a cyfrifoedd heb eu cloi fydd yn gweithio. Tra bod yn aros yn wag yr hyn sy'n rhagosodedig yw'r holl weinyddwyr lleol.
+        title: Dilyn diofyn i ddefnyddwyr newydd
+      contact_information:
+        email: E-bost busnes
+        username: Enw defnyddiwr cyswllt
+      custom_css:
+        desc_html: Addasu gwedd gyda CSS wedi lwytho ar bob tudalen
+        title: CSS wedi'i addasu
+      hero:
+        desc_html: Yn cael ei arddangos ar y dudadlen flaen. Awgrymir 600x100px oleia. Pan nad yw wedi ei osod, mae'n ymddangos fel mân-lun yr achos
+        title: Delwedd arwr
+      mascot:
+        desc_html: I'w arddangos ar nifer o dudalennau. Awgrymir 293x205px o leiaf. Pan nad yw wedi ei osod, cwympo nôl i'r mascot rhagosodedig
+        title: Llun mascot
+      peers_api_enabled:
+        desc_html: Enwau parth y mae'r achos hwn wedi dod ar ei draws yn y ffedysawd
+        title: Cyhoeddi rhestr o achosion dargynfyddiedig
+      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
+      registrations:
+        closed_message:
+          desc_html: I'w arddangos ar y dudalen flaen wedi i gofrestru cau. Mae modd defnyddio tagiau HTML
+          title: Neges gofrestru caeëdig
+        deletion:
+          desc_html: Caniatau i unrhywun i ddileu eu cyfrif
+          title: Agor dileu cyfrif
+        min_invite_role:
+          disabled: Neb
+          title: Caniatau gwahoddiadau gan
+        open:
+          desc_html: Caniatau i unrhywun greu cyfrif
+          title: Agor cofrestru
+      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
+      show_staff_badge:
+        desc_html: Dangos bathodyn staff ar dudalen defnyddiwr
+        title: Dangos bathodyn staff
+      site_description:
+        desc_html: Paragraff agoriadol ar y dudalen flaen. Disgrifiwch yr hyn sy'n arbennig am y gweinydd Mastodon hwn ac unrhywbeth arall o bwys. Mae modd defnyddio tagiau HTML <code>&lt;a&gt;</code> a <code>&lt;em&gt;</code>.
+        title: Disgrifiad achos
+      site_description_extended:
+        desc_html: Lle da ar gyfer eich cod ymddygiad, rheolau, canllawiau a phethau eraill sy'n gwneud eich achos yn whanol. Mae modd i chi ddefnyddio tagiau HTML
+        title: Gwybodaeth bellach wedi ei addasu
+      site_short_description:
+        desc_html: Yn cael ei ddangos yn bar ar yr ochr a tagiau meto. Digrifiwch beth yw Mastodon a beth sy'n gwneud y gweinydd hwn mewn un paragraff. Os yn wag, wedi ei ragosod i ddangos i disgrifiad yr achos.
+        title: Disgrifiad byr o'r achos
+      site_terms:
+        desc_html: Mae modd i chi ysgrifennu polisi preifatrwydd, termau gwasanaeth a cyfreitheg arall eich hun. Mae modd defnyddio tagiau HTML
+        title: Termau gwasanaeth wedi eu haddasu
+      site_title: Enw'r achos
+      thumbnail:
+        desc_html: Ceith ei ddefnyddio ar gyfer rhagolygon drwy OpenGraph a'r API. Argymhellir 1200x630px
+        title: Mân-lun yr achos
+      timeline_preview:
+        desc_html: Dangos ffrwd gyhoeddus ar y dudalen lanio
+        title: Rhagolwg o'r ffrwd
+      title: Gosodiadau'r wefan
+    statuses:
+      back_to_account: Yn ôl i dudalen y cyfrif
+      batch:
+        delete: Dileu
+        nsfw_off: Marcio fel nad yw'n sensitif
+        nsfw_on: Marcio'n sensitif
+      failed_to_execute: Methwyd a gweithredu
+      media:
+        title: Cyfryngau
+      no_media: Dim cyfryngau
+      no_status_selected: Ni newidwyd dim statws achos ni ddewiswyd dim un
+      title: Statysau cyfrif
+      with_media: A chyfryngau
+    subscriptions:
+      callback_url: URL galw-nôl
+      confirmed: Wedi'i gadarnhau
+      expires_in: Dod i ben ymhen
+      last_delivery: Danfoniad diwethaf
+      title: WebSub
+      topic: Pwnc
+    tags:
+      accounts: Cyfrifon
+      hidden: Cudd
+      name: Hashnod
+    title: Gweinyddiaeth
+    warning_presets:
+      delete: Dileu
+      edit: Golygu
+  admin_mailer:
+    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}}
+  application_mailer:
+    notification_preferences: Newid gosodiadau e-bost
+    salutation: "%{name},"
+    settings: 'Newid gosodiadau e-bost: %{link}'
+    view: 'Gweld:'
+    view_profile: Gweld proffil
+    view_status: Gweld statws
+  applications:
+    created: Cais wedi ei greu'n llwyddiannus
+    destroyed: Cais wedi ei ddileu'n llwyddiannus
+    invalid_url: Mae'r URL a ddarparwyd yn annilys
+    regenerate_token: Adfywio tocyn mynediad
+    token_regenerated: Adfywiwyd y tocyn mynediad yn llwyddiannus
+    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>.
+    change_password: Cyfrinair
+    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.
+    didnt_get_confirmation: Heb dderbyn cyfarwyddiadau cadarnhau?
+    forgot_password: Wedi anghofio'ch cyfrinair?
+    invalid_reset_password_token: Tocyn ailosod cyfrinair yn annilys neu wedi dod i ben. Gwnewch gais am un newydd os gwelwch yn dda.
+    login: Mewngofnodi
+    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
+    resend_confirmation: Ailanfon cyfarwyddiadau cadarnhau
+    reset_password: Ailosod cyfrinair
+    security: Diogelwch
+    set_new_password: Gosod cyfrinair newydd
+  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
+    follow: Dilyn
+    follow_request: 'Yr ydych wedi anfon cais dilyn at:'
+    following: 'Llwyddiant! Yr ydych yn awr yn dilyn:'
+    post_follow:
+      close: Neu, gallwch gau'r ffenest hon.
+      return: Dangos proffil y defnyddiwr
+      web: I'r wê
+    title: Dilyn %{acct}
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count}awr"
+      about_x_months: "%{count}mis"
+      about_x_years: "%{count}blwyddyn"
+      almost_x_years: "%{count}blwyddyn"
+      half_a_minute: Newydd fod
+      less_than_x_minutes: "%{count}m"
+      less_than_x_seconds: Newydd fod
+      over_x_years: "%{count}blwyddyn"
+      x_days: "%{count}dydd"
+      x_minutes: "%{count}m"
+      x_months: "%{count}mis"
+      x_seconds: "%{count}eiliad"
+  deletes:
+    bad_password_msg: Go dda, hacwyr! Cyfrinair anghywir
+    confirm_password: Mewnbynnwch eich cyfrinair presennol i gadarnhau mai chi sydd yno
+    description_html: Bydd hyn yn cael gwared ar gynnwys o'ch cyfrif <strong>am byth heb fodd i'w adfer</strong> ac yn diffodd y cyfrif. Caiff eich eich enw defnyddiwr ei gadw i atal unrhyw ddynwarediadau yn y dyfodol.
+    proceed: Dileu cyfrif
+    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
+  errors:
+    '403': Nid oes gennych ganiatad i weld y dudalen hon.
+    '404': Nid yw'r dudalen yr oeddech yn chwilio amdani'n bodoli.
+    '410': Nid yw'r dudalen yr oeddech yn chwilio amdani'n bodoli mwyach.
+    '422':
+      content: Methwyd i ddilysu diogelwch. A ydych chi'n blocio cwcîs?
+      title: Methwyd i ddilysu diogelwch
+    '429': Wedi'i arafu
+    '500':
+      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.
+  exports:
+    archive_takeout:
+      date: Dyddiad
+      download: Lawrlwytho eich archif
+      hint_html: Mae modd gwneud cais am archif o'ch <strong>twtiau a'ch cyfryngau</strong>. Bydd y data sy'n cael ei allforio ar fformat ActivityPub, a ellir ei ddarllen gyda unrhyw feddalwaedd sy'n cydymffurfio. Mae modd gwneud cais am archif bob 7 diwrnod.
+      in_progress: Cyfansoddi eich archif...
+      request: Gwneud cais am eich archif
+      size: Maint
+    blocks: Yr ydych yn blocio
+    csv: CSV
+    follows: Yr ydych yn dilyn
+    mutes: Yr ydych yn tawelu
+    storage: Storio cyfryngau
+  filters:
+    contexts:
+      home: Ffrwd gartref
+      notifications: Hysbysiadau
+      public: Ffrwd gyhoeddus
+      thread: Sgyrsiau
+    edit:
+      title: Golygu hidlydd
+    errors:
+      invalid_context: Dim cyd-destun neu cyd-destun annilys wedi ei ddarparu
+      invalid_irreversible: Mae hidlo anadferadwy ond yn gweithio yng nghyd-destun cartref neu hysbysiadau
+    index:
+      delete: Dileu
+      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:
+    changes_saved_msg: Llwyddwyd i gadw y newidiadau!
+    copy: Copïo
+    save_changes: Cadw newidiadau
+    validation_errors: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod os gwelwch yn dda
+  imports:
+    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
+      following: Rhestr dilyn
+      muting: Rhestr tawelu
+    upload: Uwchlwytho
+  in_memoriam_html: In Memoriam.
+  invites:
+    delete: Dadactifadu
+    expired: Wedi darfod
+    expires_in:
+      '1800': 30 munud
+      '21600': 6 awr
+      '3600': 1 awr
+      '43200': 12 awr
+      '604800': 1 wythnos
+      '86400': 1 dydd
+    expires_in_prompt: Byth
+    generate: Cynhyrchu
+    invited_by: 'Cawsoch eich gwahodd gan:'
+    max_uses: "%{count} defnydd"
+    max_uses_prompt: Dim terfyn
+    prompt: Cynhyrchwch a rhannwch ddolenni gyda eraill i ganiatau mynediad i'r achos hwn
+    table:
+      expires_at: Darfod ar
+      uses: Defnyddiau
+    title: Gwahodd pobl
+  lists:
+    errors:
+      limit: Yr ydych wedi cyrraedd uchafswm nifer y rhestrau posib
+  media_attachments:
+    validations:
+      images_and_video: Ni ellir ychwanegu fideo at statws sy'n cynnwys delweddau'n barod
+      too_many: Ni ellir ychwanegu mwy na 4 dogfen
+  migrations:
+    acct: enwdefnyddiwr@parth y cyfrif newydd
+    currently_redirecting: 'Mae eich proffil wedi ei osod i ailgyfeirio i:'
+    proceed: Cadw
+    updated_msg: Diweddarwyd gosodiad mudo eich cyfrif yn llwyddiannus!
+  moderation:
+    title: Cymedroli
+  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"
+      title: Yn eich absenoldeb...
+    favourite:
+      body: 'Cafodd eich statws ei hoffi gan %{name}:'
+      subject: Hoffodd %{name} eich statws
+      title: Ffefryn newydd
+    follow:
+      body: Mae %{name} bellach yn eich dilyn!
+      subject: Mae %{name} bellach yn eich dilyn
+      title: Dilynwr newydd
+    follow_request:
+      action: Rheoli ceisiadau dilyn
+      body: Mae %{name} wedi gwneud cais i'ch dilyn
+      subject: 'Dilynwr yn aros: %{name}'
+      title: Cais dilynwr newydd
+    mention:
+      action: Ateb
+      body: 'Caswoch eich sôn amdano gan %{name} yn:'
+      subject: Cawsoch eich sôn amdano gan %{name}
+      title: Crywbylliad newydd
+    reblog:
+      body: 'Cafodd eich statws ei fŵstio gan %{name}:'
+      subject: Bŵstiodd %{name} eich statws
+      title: Hwb newydd
+  number:
+    human:
+      decimal_units:
+        format: "%n%u"
+        units:
+          billion: B
+          million: M
+          quadrillion: Q
+          thousand: K
+          trillion: T
+  pagination:
+    newer: Diweddarach
+    next: Nesaf
+    older: HÅ·n
+    prev: Blaenorol
+    truncate: "&hellip;"
+  preferences:
+    languages: Ieithoedd
+    other: Arall
+    publishing: Cyhoeddi
+    web: Gwe
+  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:'
+  remote_unfollow:
+    error: Gwall
+    title: Teitl
+    unfollowed: Dad-ddilynwyd
+  sessions:
+    activity: Gweithgaredd ddiwethaf
+    browser: Porwr
+    browsers:
+      alipay: Alipay
+      blackberry: Blackberry
+      chrome: Chrome
+      edge: Microsoft Edge
+      electron: Electron
+      firefox: Firefox
+      generic: Porwr anhysbys
+      ie: Internet Explorer
+      micro_messenger: MicroMessenger
+      nokia: Porwr Nokia S40 Ovi
+      opera: Opera
+      otter: Otter
+      phantom_js: PhantomJS
+      qq: Porwr QQ
+      safari: Safari
+      uc_browser: UCBrowser
+      weibo: Weibo
+    current_session: Sesiwn cyfredol
+    description: "%{browser} ar %{platform}"
+    explanation: Dyma'r porwyr gwê sydd wedi mewngofnodi i'ch cyfrif Mastododon ar hyn o bryd.
+    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: platfform anhysbys
+      windows: Windows
+      windows_mobile: Windows Mobile
+      windows_phone: Windows Phone
+    revoke: Diddymu
+    revoke_success: Sesiwn wedi ei ddiddymu yn llwyddiannus
+    title: Sesiynau
+  settings:
+    authorized_apps: Apiau awdurdodedig
+    back: Yn ôl i Mastodon
+    delete: Dileu cyfrif
+    development: Datblygu
+    edit_profile: Golygu proffil
+    export: Allforio data
+    followers: Dilynwyr awdurdodedig
+    import: Mewnforio
+    migrate: Mudo cyfrif
+    notifications: Hysbysiadau
+    preferences: Dewisiadau
+    settings: Gosodiadau
+    two_factor_authentication: Awdurdodi dau-gam
+    your_apps: Eich rhaglenni
+  statuses:
+    attached:
+      description: 'Ynghlwm: %{attached}'
+      image: "%{count} o luniau"
+      video:
+        few: "%{count} fideo"
+        many: "%{count} fideo"
+        one: "%{count} fideo"
+        other: "%{count} fideo"
+        two: "%{count} fideo"
+        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}'
+    language_detection: Canfod iaith yn awtomataidd
+    open_in_web: Agor yn y wê
+    over_character_limit: wedi mynd heibio'r uchafswm nodyn o %{max}
+    pin_errors:
+      limit: Yr ydych wedi pinio yr uchafswm posib o dŵtiau
+      ownership: Ni ellir pinio tŵt rhywun arall
+      private: Ni ellir pinio tŵt nad yw'n gyhoeddus
+      reblog: Ni ellir pinio bŵstiau
+    show_more: Dangos mwy
+    sign_in_to_participate: Mengofnodwch i gymryd rhan yn y sgwrs
+    title: '%{name}: "%{quote}"'
+    visibilities:
+      private: Dilynwyr yn unig
+      private_long: Dangos i ddilynwyr yn unig
+      public: Cyhoeddus
+      public_long: Gall pawb weld
+      unlisted: Heb ei restru
+      unlisted_long: Gall pawb weld, ond heb ei restru ar ffrydiau cyhoeddus
+  stream_entries:
+    pinned: Tŵt wedi'i binio
+    reblogged: hybwyd
+    sensitive_content: Cynnwys sensitif
+  terms:
+    body_html: |
+      <h2>Polisi Preifatrwydd</h2>
+      <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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Beth ydym yn defnyddio eich gywbodaeth ar ei gyfer?</h3>
+
+      <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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">Sut ydym yn amddiffyn eich gwybodaeth?</h3>
+
+      <p>Mae gennym amryw o fesurau diogelwch er mwyn cynnal diogelwch eich gwybodaeth bersonol pan yr ydych yn mewnosod, cyflwyno neu'n cael mynediad at eich gwybodaeth bersonol. Ymysg pethau eraill, mae sesiwn eich porwr, ynghyd a'r traffig rhwng eich rhaglenni a'r API wedi eu diogelu gan SSL, ac mae'ch cyfrinair yn cael ei stwnshio drwy ddefnyddio algorithm cryf un-ffordd. Gallwch alluogi dilysu dau-gam er mwyn cryfhau diogelwch mynediad i'ch cyfrif ymhellach.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">Beth yw ein polisi cadw data?</h3>
+
+      <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>
+      </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>
+
+      <p>Mae modd i chi ddileu eich cyfrif heb ei adfer ar unrhyw bryd</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Ydyn ni'n defnyddio cwcis?</h3>
+
+      <p>Ydyn. Dogfennau bach sy'n cael eu trosglwyddo i ddisg galed eich cyfrifiadur drwy eich porwr gan wefan neu wasanaeth yw cwcis (os ydych yn eu caniatau). Galluoga'r cwcis hyn i'r wefan i adnabod eich porwr ac, os oes gennych gyfrif wedi ei gofrestru, ei gysylltu gyda'r cyfrif yr ydych wedi ei gofrestru.</p>
+
+      <p>Rydym yn defnyddio cwcis i ddeall a chadw eich dewisiadau ar gyfer ymweliadau yn y dyfodol.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Ydyn ni'n datgelu unrhyw wybodaeth i bartïoedd allanol?</h3>
+
+      <p>Nid ydym yn gwerthu, cyfnewid neu mewn unrhyw ddull yn trosglwyddo i bartïoedd allanol eich gwybodaeth bersonol. Nid yw hyn yn cynnwys trydydd partïon yr ydym yn ymddiried ynddynt sy'n ein cynorthwyo i weithredu ein gwefan, cynnal ein busnes neu'ch gwasanaethu chi, cyhyd a bod y partïoedd hynny yn cytuno i gadw'r wybodaeth yma'n gyfrinachol. Mae'n bosib i ni ryddhau eich gwybodaeth pan yr ydym yn credu fod ei ryddhau yn briodol er mwyn cydymffurfio a'r gyfraith, gorfodi ein polisiau, neu i amddiffyn hawliau, eiddo neu diogelwch eraill.</p>
+
+      <p>Gall eich cynnwys cyhoeddus gael ei lawrlwytho gan weinyddwyr eraill yn y rhwydwaith. Mae eich tŵtiau cyhoeddus a'r rhai dilynwyr yn unig yn cael eu hanfon i'r gweinyddwyr sy'n lletya eich dilynwyr, tra bod negeseuon uniongrychol yn cael eu hanfon at weinyddwyr y derbynwyr, cyn belled a fod y dilynwyr neu'r derbynwyr hynny yn bodoli ar weinydd gwahanol i'r un hwn.</p>
+
+      <p>Pan yr ydych yn caniatau y rhaglen hwn i ddefnyddio'ch cyfrif, yn dibynnu ar sgôp yr hyn yr ydych yn caniatau, gallai gael mynediad at eich gwybodaeth proffil cyhoeddus, eich rhestr dilynwyr, eich dilynwyr, eich rhestrau, eich holl dŵtiau a'ch ffefrynnau. Ni all rhaglenni byth gael mynediad at eich cyfeiriad e-bost na chwaith eich cyfrinair.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Defnydd o'r wefan gan blant</h3>
+
+      <p>Os yw'r gweinydd hwn yn yr UE neu'r EEA: Mae ein gwefan, ein nwyddau a'n gwasanaethau oll wedi eu cyfeirio at bobl sydd dros 16 mlwydd oed. Os ydych o dan 16, yn ôl gofyniad y GDPR (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>) peidiwch a defnyddio'r wefan hon.</p>
+
+      <p>Os yw'r gweinydd hwn yn UDA: Mae ein gwefan, ein nwyddau a'n gwasanaethau oll wedi eu cyfeirio at bobl sydd dros 13 mlwydd oed oleiaf. Os ydych o dan 13 mlwydd oed, yn ôl gofyniad COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) peidiwch a defnyddio'r wefan hon.</p>
+
+      <p>Mae gofynion y gyfraith yn gallu bod yn wahanol os yw'r gweinydd hwn mewn awdurdodaeth wahanol.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Newidiadau i'n Polisi Preifatrwydd</h3>
+
+      <p>Os ydyn yn penderfynnu i newid ein polisi preifatrwydd, fe wnawn ni roi'r newidiadau hynny ar y dudalen hon.</p>
+
+      <p>Mae'r ddogfen hon yn CC-BY-SA. Cafodd ei ddiweddaru diwethaf ar y 7fed o Fawrth, 2018.</p>
+
+      <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
+    mastodon-light: Mastodon (golau)
+  time:
+    formats:
+      default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
+  two_factor_authentication:
+    code_hint: Mewnbynwch y côd a grewyd gan eich ap dilysu i gadarnhau
+    description_html: Os ydych yn galluogi <strong>awdurdodi dau-gam</strong>, bydd mewngofnodi yn gofyn i chi fod a'ch ffôn gerllaw er mwyn cynhyrchu tocyn i chi gael mewnbynnu.
+    disable: Diffodd
+    enable: Galluogi
+    enabled: Awdurdodi dau-gam wedi'i alluogi
+    enabled_success: Awdurdodi dau-gam wedi'i alluogi'n llwyddiannus
+    generate_recovery_codes: Cynhyrchu côdau adfer
+    instructions_html: "<strong>Sganiwch y côd QR yn Google Authenticator neu ap TOTP tebyg ar eich ffôn</strong>. O hyn ymlaen, bydd yr ap hwnnw yn cynhyrchu tocynnau y bydd rhaid i chi fewnbynnu tra'n mewngofnodi."
+    lost_recovery_codes: Mae côdau adfer yn caniatau i chi gael mynediad i'ch cyfrif eto os ydych yn colli'ch ffôn. Os ydych wedi colli eich côdau adfer, mae modd i chi gynhyrchu nhw eto yma. Bydd eich hen gôdau wedyn yn annilys.
+    manual_instructions: 'Os nad ydych yn gallu sganio côd QR ac angen ei fewnbynnu a llaw, dyma''r gyfrinach testun-plaen:'
+    recovery_codes: Creu copi wrth gefn o gôdau adfywio
+    recovery_codes_regenerated: Llwyddwyd i ail greu côdau adfywio
+    recovery_instructions_html: Os ydych byth yn colli mynediad i'ch ffôn, mae modd i chi ddefnyddio un o'r côdau adfywio isod i ennill mynediad i'ch cyfrif eto. <strong>Cadwch y côdau adfywio yn saff</strong>. Er enghraifft, gallwch eu argraffu a'u cadw gyda dogfennau eraill pwysig.
+    setup: Sefydlu
+    wrong_code: Roedd y cod y mewnbynnwyd yn annilys! A yw'r amser gweinydd ac amser dyfais yn gywir?
+  user_mailer:
+    backup_ready:
+      explanation: Fe wnaethoch chi gais am gopi wrth gefn llawn o'ch cyfrif Mastodon. Mae nawr yn barod i'w lawrlwytho!
+      subject: Mae eich archif yn barod i'w lawrlwytho
+      title: Allfudo archif
+    warning:
+      title:
+        disable: Cyfrif wedi'i rewi
+        none: Rhybudd
+        silence: Cyfrif cyfyngedig
+        suspend: Cyfrif wedi'i rewi
+    welcome:
+      edit_profile_action: Sefydlu proffil
+      edit_profile_step: Mae modd i chi addasu eich proffil drwy uwchlwytho afatar, pennawd, drwy newid eich enw arddangos a mwy. Os hoffech chi adolygu dilynwyr newydd cyn iddynt gael caniatad i'ch dilyn, mae modd i chi gloi eich cyfrif.
+      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_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.
+      subject: Croeso i Mastodon
+      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!
+      tips: Awgrymiadau
+      title: Croeso, %{name}!
+  users:
+    follow_limit_reached: Nid oes modd i chi ddilyn mwy na %{limit} o bobl
+    invalid_email: Mae'r cyfeiriad e-bost hwn yn annilys
+    invalid_otp_token: Côd dau-ffactor annilys
+    otp_lost_help_html: Os colloch chi fynediad i'r ddau, mae modd i chi gysylltu a %{email}
+    seamless_external_login: Yr ydych wedi'ch mewngofnodi drwy wasanaeth allanol, felly nid yw gosodiadau cyfrinair ac e-bost ar gael.
+    signed_in_as: 'Wedi mewngofnodi fel:'
+  verification:
+    explanation_html: 'Mae modd i chi <strong>ddilysu eich hun fel perchenog y dolenni yn metadata eich proffil</strong>. Rhaid i''r wefan a dolen iddi gynnwys dolen yn ôl i''ch proffil Mastodon. <strong>Rhaid</strong> i''r ddolen yn ôl gael nodwedd <code>rel="fi"</code>. Nid oes ots beth yw cynnwys testun y ddolen. Dyma enghraifft:'
+    verification: Dilysu
diff --git a/config/locales/da.yml b/config/locales/da.yml
index 0e3da55f19001c168bd4d2856e09736e8bd72f83..ca4ff32dac53e28fdc9a478a72fa149a0be2b766 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -1,17 +1,17 @@
 ---
 da:
   about:
-    about_hashtag_html: Disse er offentlige toots der indeholder tagget <strong>#%{hashtag}</strong>. Du kan interagere med dem hvis du har en konto hvor som helst i fediverset.
+    about_hashtag_html: Disse er offentlige trut der indeholder tagget <strong>#%{hashtag}</strong>. Du kan interagere med dem hvis du har en konto hvor som helst i fediverset.
     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.
     contact: Kontakt
     contact_missing: Ikke sat
     contact_unavailable: Ikke tilgængeligt
-    description_headline: Hvad er %{domain}?
-    domain_count_after: andre instancer
-    domain_count_before: Forbundet til
+    documentation: Dokumentation
     extended_description_html: |
       <h3>Et godt sted for regler</h3>
       <p>Den udvidede beskrivelse er endnu ikke blevet opsat.</p>
@@ -20,42 +20,59 @@ da:
       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 multimedie advarsler, kan du udtrykke dig på en hvilken som helst måde du ønsker.
+      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 instancer
+    other_instances: Liste over instanser
+    privacy_policy: Privatlivspolitik
     source_code: Kildekode
-    status_count_after: statusser
+    status_count_after:
+      one: status
+      other: statusser
     status_count_before: Som har skrevet
-    user_count_after: brugere
+    terms: Vilkår for service
+    user_count_after:
+      one: bruger
+      other: brugere
     user_count_before: Hjem til
     what_is_mastodon: Hvad er Mastodon?
   accounts:
+    choices_html: "%{name}s valg:"
     follow: Følg
-    followers: Følgere
+    followers:
+      one: Følger
+      other: Følgere
     following: Følger
-    media: Multimedia
+    joined: Tilmeldt den %{date}
+    link_verified_on: Ejerskabet af dette link blev tjekket den %{date}
+    media: Medier
     moved_html: "%{name} er flyttet til %{new_profile_link}:"
     network_hidden: Denne information er ikke tilgængelig
     nothing_here: Der er intet her!
-    people_followed_by: Folk some %{name} følger
+    people_followed_by: Folk som %{name} følger
     people_who_follow: Folk der følger %{name}
-    posts: Dyt
-    posts_with_replies: Toots og svar
-    remote_follow: Følg fra andre instancer
-    reserved_username: Brugernavnet er reserveret
+    pin_errors:
+      following: Du er nødt til at følge den person du ønsker at støtte
+    posts:
+      one: Trut
+      other: Trut
+    posts_tab_heading: Trut
+    posts_with_replies: Trut og svar
+    reserved_username: Brugernavnet er allerede taget
     roles:
       admin: Administrator
       bot: Robot
       moderator: Moderator
     unfollow: Følg ikke længere
   admin:
+    account_actions:
+      action: Udfør handling
     account_moderation_notes:
-      create: Læg en kommentar
+      create: Læg en note
       created_msg: Moderator notat succesfuldt oprettet!
       delete: Slet
       destroyed_msg: Moderator notat succesfuldt destrueret!
@@ -96,7 +113,7 @@ da:
         remote: Fjernt
         title: Placering
       login_status: Status på login
-      media_attachments: Multimedie bilag
+      media_attachments: Medie bilag
       memorialize: Omdan til et memoriam
       moderation:
         all: Alle
@@ -107,12 +124,8 @@ da:
       most_recent_activity: Seneste aktivitet
       most_recent_ip: Senest IP
       not_subscribed: Ikke abonneret
-      order:
-        alphabetic: Alfabetisk
-        most_recent: Seneste
-        title: Rækkefølge
       outbox_url: Link til udgående
-      perform_full_suspension: Udfør fuld udelukkelse
+      perform_full_suspension: Udeluk
       profile_url: Link til profil
       promote: Forfrem
       protocol: Protokol
@@ -137,12 +150,13 @@ da:
       search: Søg
       shared_inbox_url: Link til delt indbakke
       show:
-        created_reports: Rapporter oprettet af denne konto
-        report: rapporter
+        created_reports: Anmeldelser oprettet af denne konto
         targeted_reports: Anmeldelser fra denne konto
       silence: Dæmp
+      silenced: Dæmpet
       statuses: Statusser
       subscribe: Abonner
+      suspended: Udelukket
       title: Konti
       unconfirmed_email: Ikke-bekræftet email
       undo_silenced: Fortryd dæmpning
@@ -180,6 +194,7 @@ da:
         unsuspend_account: "%{name} fjernede udelukkelsen fra %{target}s konto"
         update_custom_emoji: "%{name} opdaterede humørikonet %{target}"
         update_status: "%{name} opdaterede status for %{target}"
+      deleted_status: "(slettet status)"
       title: Revisionslog
     custom_emojis:
       by_domain: Domæne
@@ -206,6 +221,27 @@ da:
       update_failed_msg: Kunne ikke opdatere det humørikon
       updated_msg: Humørikon succesfuldt opdateret!
       upload: Læg op
+    dashboard:
+      backlog: ophobede jobs
+      config: Konfiguration
+      feature_deletions: Konto sletninger
+      feature_invites: Invitations links
+      feature_registrations: Registreringer
+      feature_relay: Føderations relæ
+      features: Funktioner
+      hidden_service: Føderation med skjulte tjenester
+      open_reports: åbne anmeldelser
+      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
+      trends: Tendenser
+      week_interactions: interaktioner denne uge
+      week_users_active: aktive denne uge
+      week_users_new: brugere denne uge
     domain_blocks:
       add_new: Tilføj ny
       created_msg: Domæne blokade bliver nu behandlet
@@ -213,18 +249,16 @@ da:
       domain: Domæne
       new:
         create: Opret blokering
+        hint: Domæne blokeringen vil ikke forhindre oprettelse af konto opslag i databasen, men vil retroaktivt og automatisk benytte specifikke moderator metoder på disse konti.
         severity:
+          desc_html: "<strong>Dæmp</strong> vil gøre denne kontos opslag usynlige til alle der ikke følger dem. <strong>Udeluk</strong> vil fjerne al kontoens indhold, medie og profildata. Brug <strong>Ingen</strong> hvis du bare ønsker at afvise medie filer."
           noop: Ingen
           silence: Dæmp
           suspend: Udeluk
         title: Ny domæne blokering
-      reject_media: Afvis multimedie filer
+      reject_media: Afvis medie filer
       reject_media_hint: Fjerner lokalt lagrede multimedie filer og nægter at hente nogen i fremtiden. Irrelevant for udelukkelser
-      severities:
-        noop: Ingen
-        silence: Dæmp
-        suspend: Udeluk
-      severity: Alvorlighed
+      reject_reports: Afvis anmeldelser
       show:
         affected_accounts:
           one: En konto i databasen påvirket
@@ -234,28 +268,47 @@ da:
           suspend: Fjern udelukkelsen af alle eksisterende konti fra dette domæne
         title: Annuller domæne blokeringen for domænet %{domain}
         undo: Fortryd
-      title: Domæne blokeringer
       undo: Fortryd
     email_domain_blocks:
       add_new: Tilføj ny
+      created_msg: Tilføjede succesfuldt email domænet til sortliste
       delete: Slet
+      destroyed_msg: Fjernede succesfuldt email domænet fra sortliste
       domain: Domæne
       new:
         create: Tilføj domæne
+        title: Ny email blokade opslag
       title: Email sortliste
+    followers:
+      back_to_account: Tilbage til konto
     instances:
-      account_count: Kendte konti
-      domain_name: Domæne
-      reset: Nulstil
-      search: Søg
       title: Kendte instanser
     invites:
+      deactivate_all: Deaktiver alle
       filter:
         all: Alle
         available: Tilgængelig
         expired: Udløbet
         title: Filtre
       title: Invitationer
+    relays:
+      add_new: Tilføj nyt relay
+      delete: Slet
+      description_html: Et <strong>federation relay</strong> er en mellemleds server der udveksler store mængder af offentlige trut mellem servere der abonnerer på og offentliggør til det. <strong>Det kan hjælpe små og mellemstore servere opdage indhold fra fediverset</strong>, hvilket der ellers ville kræve at lokale brugere manuelt følger andre folk på fjerne servere.
+      disable: Deaktiver
+      disabled: Deaktiveret
+      enable: Aktiver
+      enable_hint: Når dette er aktiveret, vil serveren abonnere på alle offentlige trut fra dette relay, og vil begynde at sende offentlige trut fra denne server dertil.
+      enabled: Aktiveret
+      inbox_url: Link til relay
+      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!
+      destroyed_msg: Anmeldelse note blev slettet!
     reports:
       account:
         note: notat
@@ -267,7 +320,6 @@ da:
       comment:
         none: Ingen
       created_at: Anmeldt
-      id: ID
       mark_as_resolved: Marker som værende løst
       mark_as_unresolved: Marker som værende uløst
       notes:
@@ -278,26 +330,41 @@ da:
         placeholder: Beskriv hvilke handlinger der er blevet udført, eller andre relevante opdateringer...
       reopen: Genåben anmeldelse
       report: 'Anmeldelse #%{id}'
-      report_contents: Indhold
       reported_account: Anmeldt konto
       reported_by: Anmeldt af
       resolved: Løst
       resolved_msg: Anmeldelse er sat til at være løst!
-      silence_account: Dæmp konto
       status: Status
-      suspend_account: Udeluk konto
-      target: MÃ¥l
       title: Anmeldelser
+      unassign: Utildel
       unresolved: Uløst
       updated_at: Opdateret
-      view: Se
     settings:
+      activity_api_enabled:
+        desc_html: Antal af lokalt opslåede statusser, aktive brugere, og nye registreringer i ugentlige opdelinger
+        title: Offentliggør samlede statistikker vedrørende brugeraktivitet
+      bootstrap_timeline_accounts:
+        desc_html: Opdel flere brugernavne ved hjælp af komma. Kun lokale og ulåste konti vil virke. Standard hvis tom er alle lokale administratorer.
+        title: Standard følger for nye brugere
       contact_information:
         email: Forretnings email
         username: Kontakt brugernavn
+      custom_css:
+        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
         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
+      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
       registrations:
+        closed_message:
+          desc_html: Vist på forsiden når registreringer er lukkede. Du kan bruge HTML tags
+          title: Besked for lukkede registreringer
         deletion:
           desc_html: Tillad alle at slette deres konto
           title: Ã…ben konto sletning
@@ -307,14 +374,31 @@ da:
         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
       show_staff_badge:
         desc_html: Vis personale emblem på en brugerside
         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
+      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
+        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
+      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
+      thumbnail:
+        desc_html: Brugt til forhåndsvisninger via OpenGraph og API. 1200x630px anbefales
+        title: Miniaturebillede for instans
       timeline_preview:
         desc_html: Vis offentlig tidslinje på landingssiden
+        title: Tidslinje forhåndsvisning
       title: Indstillinger for side
     statuses:
       back_to_account: Tilbage til kontosiden
@@ -326,46 +410,67 @@ da:
       media:
         title: Multimedier
       no_media: Ingen multimedier
+      no_status_selected: Ingen statusser blev ændret eller ingen blev valgt
       title: Konto statusser
       with_media: Med multimedier
     subscriptions:
+      callback_url: Callback-URL
       confirmed: Bekræftet
       expires_in: Udløber om
       last_delivery: Sidste levering
+      title: Websub
       topic: Emne
+    tags:
+      accounts: Kontoer
+      hidden: Skjult
     title: Administration
   admin_mailer:
     new_report:
       body: "%{reporter} har anmeldt %{target}"
       body_remote: Nogen fra %{domain} har anmeldt %{target}
+      subject: Ny anmeldelse for %{instance} (#%{id})
   application_mailer:
-    notification_preferences: Ændre email indstillinger
+    notification_preferences: Ændre email præferencer
     salutation: "%{name},"
-    settings: 'Ændre email indstillinger: %{link}'
+    settings: 'Ændre email præferencer: %{link}'
     view: 'Se:'
     view_profile: Se profil
     view_status: Se status
   applications:
+    created: Applikation blev oprettet
+    destroyed: Applikation er blevet slettet
     invalid_url: Det angivne URL er ugyldigt
+    regenerate_token: Regenerer adgangs token
+    token_regenerated: Adgangs token blev regenereret
     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
+    delete_account_html: Hvis du ønsker at slette din konto, kan du <a href="%{path}">gøre det her</a>. Du vil blive bedt om bekræftelse.
     didnt_get_confirmation: Har du endnu ikke modtaget instrukser for bekræftelse?
     forgot_password: Glemt dit kodeord?
+    invalid_reset_password_token: Adgangskode nulstillings token er ugyldig eller udløbet. Anmod venligst om en ny.
     login: Log ind
     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
     set_new_password: Sæt et nyt kodeord
   authorize_follow:
     already_following: Du følger allerede denne konto
+    error: Der opstod desværre en fejl under søgningen af denne fjerne konto
     follow: Følg
     follow_request: 'Du har anmodet om at følge:'
     following: 'Succes! Du følger nu:'
@@ -378,31 +483,49 @@ da:
     distance_in_words:
       about_x_hours: "%{count}t"
       about_x_months: "%{count} måneder"
+      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_title: Tilgængelighed af delt indhold
   errors:
     '403': Du har ikke tilladelse til at se denne side.
     '404': Den side du leder efter findes ikke.
     '410': Den side du leder efter findes ikke mere.
     '422':
+      content: Sikkerhedsbekræftelse mislykkedes. Blokerer du cookies?
       title: Sikkerheds godkendelse mislykkedes
+    '429': Droslet
     '500':
       content: Beklager men der gik noget galt i vores ende.
       title: Siden er ikke korrekt
+    noscript_html: For at bruge Mastodon web applikationen, aktiver JavaScript. Alternativt kan du prøve en af disse <a href="%{apps_path}">apps</a> til Mastodon for din platform.
   exports:
     archive_takeout:
       date: Dato
       download: Hent dit arkiv
+      hint_html: Du kan anmode om et arkiv af dine <strong>trut og oplagt medie</strong>. Den eksporterede data vil være i ActivityPub formattet, læseligt af enhvert kompatibel program. Du kan anmode om et arkiv en gang om ugen.
+      in_progress: Udarbejder dit arkiv...
+      request: Anmod om dit arkiv
       size: Størrelse
     blocks: Du blokerer
+    csv: CSV
     follows: Du følger
     mutes: Du dæmper
+    storage: Medie lager
   filters:
     contexts:
       home: Hjemme tidslinje
@@ -411,6 +534,9 @@ da:
       thread: Samtaler
     edit:
       title: Rediger filter
+    errors:
+      invalid_context: Ingen eller ugyldig kontekst angivet
+      invalid_irreversible: Uigenkaldelig filtrering virker kun med hjem eller notifikations kontekst
     index:
       delete: Slet
       title: Filtrer
@@ -418,20 +544,36 @@ da:
       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…
+    resources: Ressourcer
   generic:
     changes_saved_msg: Ændringerne blev gemt!
-    powered_by: drevet af %{link}
+    copy: Kopier
     save_changes: Gem ændringer
+    validation_errors:
+      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.
+    success: Dine data blev succesfuldt uploaded og vil nu blive behandlet hurtigst muligt
     types:
       blocking: Blokeringsliste
       following: Følgningsliste
       muting: Liste over dæmpninger
     upload: Læg op
+  in_memoriam_html: Til minde om.
   invites:
     delete: Deaktiver
     expired: Udløbet
@@ -445,28 +587,54 @@ da:
     expires_in_prompt: Aldrig
     generate: Generer
     invited_by: 'Du er blevet inviteret af:'
+    max_uses:
+      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
     table:
       expires_at: Udløber
+      uses: Benyttelser
     title: Inviter folk
+  lists:
+    errors:
+      limit: Du har nået det højeste antal lister
   media_attachments:
     validations:
+      images_and_video: Kan ikke vedhæfte en video til en status der allerede har billeder
       too_many: Kan ikke vedhæfte mere en 4 filer
   migrations:
     acct: username@domain af den nye konto
     currently_redirecting: 'Din profil er sat til at henvise til:'
     proceed: Gem
+    updated_msg: Dine konti migrærings indstillinger blev opdateret!
   moderation:
     title: Moderatering
   notification_mailer:
     digest:
       action: Se alle notifikationer
+      body: Her er en kort gennemgang af de beskeder du gik glip af siden dit sidste besøg den %{since}
       mention: "%{name} nævnte dig i:"
+      new_followers_summary:
+        one: Du har også fået dig en ny følger mens du var væk! Sådan!
+        other: Du har også fået %{count} nye følgere mens du var væk! Fantastisk!
+      subject:
+        one: "1 ny notifikation siden du sidst var her \U0001F418"
+        other: "%{count} nye notifikationer siden du sidst var her \U0001F418"
       title: Mens du var væk...
+    favourite:
+      body: 'Din status blev favoriseret af %{name}:'
+      subject: "%{name} favoriserede din status"
+      title: Ny favorit
     follow:
       body: "%{name} følger dig nu!"
       subject: "%{name} følger dig nu"
       title: Ny følger
+    follow_request:
+      action: Håndter følgeranmodninger
+      body: "%{name} har anmodet om at følge dig"
+      subject: 'Følger afventer: %{name}'
+      title: Ny følgeranmodning
     mention:
       action: Svar
       body: 'Du blev nævnt af %{name} i:'
@@ -479,49 +647,90 @@ 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
     older: Ældre
     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
+    no_account_html: Har du ikke en konto? Du kan <a href='%{sign_up_path}' target='_blank'>oprette dig her</a>
+    proceed: Fortsæt for at følge
+    prompt: 'Du er ved at følge:'
   remote_unfollow:
     error: Fejl
     title: Titel
     unfollowed: Følger ikke længere
   sessions:
+    activity: Sidste aktivitet
+    browser: Browser
     browsers:
+      alipay: Ali-pay
       blackberry: Blackberry OS
       chrome: Google Chrome
+      edge: Microsoft edge
+      electron: Elektron
       firefox: Mozilla Firefox
       generic: Ukendt browser
       ie: IE
+      micro_messenger: Micromessenger
+      nokia: Nokia S40 ovi browser
+      opera: Opera browser
+      otter: Odder
+      phantom_js: FantomJS
+      qq: QQ browser
+      safari: Apple Safari
+      uc_browser: UCbrowser
+      weibo: Weibo browser
+    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
+      windows_mobile: Windows mobil
+      windows_phone: Windows fon
+    revoke: Tilbagekald
+    revoke_success: Sessionen blev tilbagekaldt
+    title: Sessioner
   settings:
     authorized_apps: Godkendte apps
     back: Tilbage til Mastodon
     delete: Sletning af konto
     development: Udvikling
     edit_profile: Rediger profil
+    export: Data eksportering
     followers: Godkendte følgere
     import: Importer
     migrate: Konto migrering
     notifications: Notifikationer
-    preferences: Indstillinger
+    preferences: Præferencer
     settings: Indstillinger
+    two_factor_authentication: To-faktor godkendelse
     your_apps: Dine applikationer
   statuses:
     attached:
@@ -532,11 +741,21 @@ da:
       video:
         one: "%{count} video"
         other: "%{count} videoer"
+    boosted_from_html: Fremhævet fra %{acct_link}
     content_warning: 'Advarsel om indhold: %{warning}'
+    disallowed_hashtags:
+      one: 'indeholdte et ikke tilladt hashtag: %{tags}'
+      other: 'indeholdte de ikke tilladte hashtags: %{tags}'
     language_detection: Opfang automatisk sprog
+    open_in_web: Ã…bn i browser
+    over_character_limit: grænsen på %{max} tegn er overskredet
     pin_errors:
-      ownership: Dun kan ikke fastgøre en anden persons toot
+      limit: Du har allerede fastgjort det maksimale antal trut
+      ownership: Du kan ikke fastgøre en anden persons trut
+      private: Ikke offentlige trut kan ikke blive fastgjort
+      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
@@ -544,24 +763,36 @@ da:
       public: Offentlig
       public_long: Alle kan se
       unlisted: Ikke listet
+      unlisted_long: Alle kan se, men vil ikke være listet på offentlige tidslinjer
   stream_entries:
-    click_to_show: Tryk for at vise
-    pinned: Fastgjort toot
+    pinned: Fastgjort trut
+    reblogged: fremhævede
     sensitive_content: Følsomt indhold
+  terms:
+    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: Mastodon
+    default: Mastodont
     mastodon-light: Mastodon (lys)
+  time:
+    formats:
+      default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
   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.
     disable: Deaktiver
     enable: Aktiver
     enabled: To-faktor godkendelse er aktiveret
     enabled_success: To-faktor godkendelse succesfuldt aktiveret
     generate_recovery_codes: Generer gendannelseskoder
+    instructions_html: "<strong>Scan denne QR kode i Google Autehnticator eller lignende TOTP app på din telefon</strong>. Fra nu af vil den app generere koder som du vil være nødt til at indtaste når du logger ind."
+    lost_recovery_codes: Gendannelseskoder vil lade dig få adgang til din konto hvis du mister din telefon. Hvis du har mistet dine gendannelseskoder, kan du regenerere dem her. Dine gamle gendannelseskoder vil blive ugyldige.
     manual_instructions: 'Hvis du ikke kan scanne QR koden er er nødt til at skrive koden ind manuelt, kan er din almindelig tekst secret:'
     recovery_codes: Reserve koder
     recovery_codes_regenerated: Reserve koder blev succesfuldt regenereret
+    recovery_instructions_html: Hvis du nogensinde mister adgang til din telefon, kan du bruge en af genoprettelses koderne forneden for at få adgang til din konto. <strong>Gem gendannelses koderne et sikkert sted</strong>. Foreksempel kan du printe dem ud og gemme dem sammen med andre vigtige dokumenter.
     setup: Sæt op
     wrong_code: Den indtastede kode var ugyldig! Er serverens tid og enhedens tid korrekte?
   user_mailer:
@@ -571,12 +802,16 @@ da:
       title: Udpluk af arkiv
     welcome:
       edit_profile_action: Opsæt profil
+      edit_profile_step: Du kan skræddersy din profil ved at uploade et profilbillede, overskrift, ændre dit visningsnavn og mere. Hvis du kunne tænke dig at gennemse nye følgere før de må følge dig, kan du låse din konto.
       explanation: Her er nogle råd til at starte med
       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.
       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
+      tip_federated_timeline: Den delte tidslinje er et brandslange agtigt indblik over Mastodon netværket. Men det inkluderer kun folk dine naboer abonnerer på, så den er ikke fuldendt.
       tip_following: Du følger som standard administratoren(e) for den server du er på. For at finde flere folk, tjek både den lokale og fælles tidslinje.
       tip_local_timeline: Den lokale tidslinje er et have af folk i %{instance}. Disse er dine umiddelbare naboer!
       tip_mobile_webapp: Hvis din mobil browser tilbyder dig at tilføje Mastodon til din hjemmeskærm, kan du modtage push meddelelser. Dette opfører sig på mange måder ligesom en almindelig app!
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 5f17803f5fb166104432f5c7afa1cf5984cf381a..b9074662e228a747d8bbb960a34fbabdccee732a 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -1,52 +1,68 @@
 ---
 de:
   about:
-    about_hashtag_html: Dies sind öffentliche Beiträge, die mit <strong>#%{hashtag}</strong> getaggt wurden. Wenn du ein Konto irgendwo im Fediversum besitzt, kannst du mit ihnen interagieren.
+    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_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:'
+    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.
     contact: Kontakt
     contact_missing: Nicht angegeben
     contact_unavailable: N/A
-    description_headline: Was ist %{domain}?
-    domain_count_after: anderen Instanzen
-    domain_count_before: Vernetzt mit
+    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: Mastodon hat von den Fehlern anderer Netzwerke gelernt und wurde mit dem Augenmerk darauf entwickelt, den Missbrauch sozialer Medien zu bekämpfen.
+      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 der Ermöglichung präziser Inhalts- und Bilderwarnungen kannst du dich so ausdrücken, wie du es möchtest.
-      real_conversation_title: Für das echte Gespräch gemacht
-      within_reach_body: Verschiedene Apps für iOS, Android und andere Plattformen erlauben dir dank unserem blühenden API-Ökosystem, dich von überall auf dem Laufenden zu halten.
+      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}
     learn_more: Mehr erfahren
     other_instances: Andere Instanzen
+    privacy_policy: Datenschutzerklärung
     source_code: Quellcode
-    status_count_after: Beiträge verfassten
-    status_count_before: die
-    user_count_after: Wesen
+    status_count_after:
+      one: Statusmeldung
+      other: Statusmeldungen
+    status_count_before: mit
+    terms: Nutzungsbedingungen
+    user_count_after:
+      one: Benutzer:in
+      other: Benutzer:innen
     user_count_before: Zuhause für
     what_is_mastodon: Was ist Mastodon?
   accounts:
+    choices_html: "%{name} empfiehlt:"
     follow: Folgen
-    followers: Folgende
+    followers:
+      one: Folgender
+      other: Folgende
     following: Folgt
+    joined: Beigetreten am %{date}
+    last_active: zuletzt aktiv
+    link_verified_on: Besitz des Links wurde überprüft am %{date}
     media: Medien
     moved_html: "%{name} ist auf %{new_profile_link} umgezogen:"
     network_hidden: Diese Informationen sind nicht verfügbar
     nothing_here: Hier gibt es nichts!
     people_followed_by: Profile, denen %{name} folgt
     people_who_follow: Profile, die %{name} folgen
-    posts: Beiträge
+    pin_errors:
+      following: Du musst dieser Person bereits folgen, um sie empfehlen zu können
+    posts:
+      one: Beitrag
+      other: Beiträge
+    posts_tab_heading: Beiträge
     posts_with_replies: Beiträge mit Antworten
-    remote_follow: Folgen
     reserved_username: Dieser Profilname ist belegt
     roles:
       admin: Admin
@@ -54,15 +70,18 @@ de:
       moderator: Moderator
     unfollow: Entfolgen
   admin:
+    account_actions:
+      action: Aktion ausführen
+      title: Moderationsaktion auf %{acct} ausführen
     account_moderation_notes:
-      create: Notiz hinterlassen
+      create: Notiz erstellen
       created_msg: Moderationsnotiz erfolgreich erstellt!
       delete: Löschen
       destroyed_msg: Moderationsnotiz erfolgreich gelöscht!
     accounts:
       are_you_sure: Bist du sicher?
       avatar: Profilbild
-      by_domain: Domäne
+      by_domain: Domain
       change_email:
         changed_msg: E-Mail-Adresse des Kontos erfolgreich geändert!
         current_email: Aktuelle E-Mail-Adresse
@@ -73,6 +92,7 @@ de:
       confirm: Bestätigen
       confirmed: Bestätigt
       confirming: Bestätigung
+      deleted: Gelöscht
       demote: Degradieren
       disable: Ausschalten
       disable_two_factor_authentication: 2FA abschalten
@@ -85,11 +105,14 @@ de:
       enable: Freischalten
       enabled: Freigegeben
       feed_url: Feed-URL
-      followers: Folger
+      followers: Folgende
       followers_url: URL des Folgenden
       follows: Folgt
+      header: Header
       inbox_url: Posteingangs-URL
+      invited_by: Eingeladen von
       ip: IP-Adresse
+      joined: Beigetreten
       location:
         all: Alle
         local: Lokal
@@ -99,6 +122,7 @@ de:
       media_attachments: Medienanhänge
       memorialize: In Gedenkmal verwandeln
       moderation:
+        active: Aktiv
         all: Alle
         silenced: Stummgeschaltet
         suspended: Gesperrt
@@ -106,22 +130,20 @@ de:
       moderation_notes: Moderationsnotizen
       most_recent_activity: Letzte Aktivität
       most_recent_ip: Letzte IP-Adresse
+      no_limits_imposed: Keine Limits eingesetzt
       not_subscribed: Nicht abonniert
-      order:
-        alphabetic: Alphabetisch
-        most_recent: Neueste
-        title: Sortierung
       outbox_url: Postausgangs-URL
-      perform_full_suspension: Vollständige Sperre durchführen
+      perform_full_suspension: Sperren
       profile_url: Profil-URL
       promote: Befördern
       protocol: Protokoll
       public: Öffentlich
       push_subscription_expires: PuSH-Abonnement läuft aus
-      redownload: Avatar neu laden
+      redownload: Profil neu laden
       remove_avatar: Profilbild entfernen
+      remove_header: Header entfernen
       resend_confirmation:
-        already_confirmed: Dieser Benutzer wurde bereits bestätigt
+        already_confirmed: Diese:r Benutzer:in wurde bereits bestätigt
         send: Bestätigungsmail erneut senden
         success: Bestätigungs-E-Mail erfolgreich gesendet!
       reset: Zurücksetzen
@@ -130,56 +152,61 @@ de:
       role: Berechtigungen
       roles:
         admin: Administrator
-        moderator: Moderator
+        moderator: Moderator:in
         staff: Mitarbeiter
         user: Nutzer
       salmon_url: Salmon-URL
       search: Suche
-      shared_inbox_url: Geteilter Posteingang URL
+      shared_inbox_url: Geteilte Posteingang-URL
       show:
-        created_reports: Meldungen durch dieses Konto
-        report: Meldung
-        targeted_reports: Meldungen über dieses Konto
+        created_reports: Erstellte Beschwerdemeldungen
+        targeted_reports: Beschwerdemeldungen von anderen
       silence: Stummschalten
+      silenced: Stummgeschaltet
       statuses: Beiträge
       subscribe: Abonnieren
+      suspended: Gesperrt
       title: Konten
       unconfirmed_email: Unbestätigte E-Mail-Adresse
       undo_silenced: Stummschaltung zurücknehmen
       undo_suspension: Sperre zurücknehmen
       unsubscribe: Abbestellen
       username: Profilname
+      warn: Warnen
       web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} hat sich die Meldung %{target} selbst zugewiesen"
         change_email_user: "%{name} hat die E-Mail-Adresse des Nutzers %{target} geändert"
         confirm_user: "%{name} hat die E-Mail-Adresse von %{target} bestätigt"
+        create_account_warning: "%{name} hat eine Warnung an %{target} gesendet"
         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 %{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 %{target} deaktiviert"
+        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  %{target} deaktiviert"
+        disable_user: "%{name} hat den Login für Benutzer:in  %{target} deaktiviert"
         enable_custom_emoji: "%{name} hat das %{target} Emoji aktiviert"
-        enable_user: "%{name} hat die Anmeldung für den Benutzer %{target} aktiviert"
-        memorialize_account: "%{name} hat %{target}s Profil in eine Gedenkseite umgewandelt"
+        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"
         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 den Benutzer %{target} zurückgesetzt"
+        reset_password_user: "%{name} hat das Passwort für di:en Benutzer:in %{target} zurückgesetzt"
         resolve_report: "%{name} hat die Meldung %{target} bearbeitet"
-        silence_account: "%{name} hat %{target}s Account stummgeschaltet"
-        suspend_account: "%{name} hat %{target}s Account gesperrt"
+        silence_account: "%{name} hat %{target}s Konto stummgeschaltet"
+        suspend_account: "%{name} hat %{target}s Konto gesperrt"
         unassigned_report: "%{name} hat die Zuweisung der Meldung %{target} entfernt"
-        unsilence_account: "%{name} hat die Stummschaltung von %{target}s Account aufgehoben"
-        unsuspend_account: "%{name} hat die Sperrung von %{target}s Account aufgehoben"
+        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"
+      deleted_status: "(gelöschter Beitrag)"
       title: Überprüfungsprotokoll
     custom_emojis:
       by_domain: Domain
@@ -206,8 +233,30 @@ de:
       update_failed_msg: Konnte dieses Emoji nicht aktualisieren
       updated_msg: Emoji erfolgreich aktualisiert!
       upload: Hochladen
+    dashboard:
+      backlog: Unerledigte Jobs
+      config: Konfiguration
+      feature_deletions: Kontolöschung
+      feature_invites: Einladungslinks
+      feature_profile_directory: Profilverzeichnis
+      feature_registrations: Registrierung
+      feature_relay: Föderations-Relay
+      features: Eigenschaften
+      hidden_service: Föderation mit versteckten Diensten
+      open_reports: Offene Meldungen
+      recent_users: Neueste Nutzer
+      search: Volltextsuche
+      single_user_mode: Einzelnutzermodus
+      software: Software
+      space: Speicherverbrauch
+      title: Übersicht
+      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
     domain_blocks:
-      add_new: Neu hinzufügen
+      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
@@ -222,11 +271,13 @@ de:
         title: Neue Domain-Blockade
       reject_media: Mediendateien ablehnen
       reject_media_hint: Entfernt lokal gespeicherte Mediendateien und verhindert deren künftiges Herunterladen. Für Sperren irrelevant
-      severities:
-        noop: Kein
-        silence: Stummschaltung
-        suspend: Sperren
-      severity: Schweregrad
+      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
+      severity:
+        silence: stummgeschaltet
+        suspend: gesperrt
       show:
         affected_accounts:
           one: Ein Konto in der Datenbank betroffen
@@ -236,8 +287,7 @@ de:
           suspend: Alle existierenden Konten dieser Domain entsperren
         title: Domain-Blockade für %{domain} zurücknehmen
         undo: Zurücknehmen
-      title: Domain-Blockaden
-      undo: Zurücknehmen
+      undo: Domainblockade zurücknehmen
     email_domain_blocks:
       add_new: Neue hinzufügen
       created_msg: E-Mail-Domain-Blockade erfolgreich erstellt
@@ -248,19 +298,47 @@ de:
         create: Blockade erstellen
         title: Neue E-Mail-Domain-Blockade
       title: E-Mail-Domain-Blockade
+    followers:
+      back_to_account: Zurück zum Konto
+      title: "%{acct}'s Follower"
     instances:
-      account_count: Bekannte Konten
-      domain_name: Domain
-      reset: Zurücksetzen
-      search: Suchen
-      title: Bekannte Instanzen
+      delivery_available: Zustellung ist verfügbar
+      known_accounts:
+        one: "%{count} bekanntes Konto"
+        other: "%{count} bekannte Accounts"
+      moderation:
+        all: Alle
+        limited: Limitiert
+        title: Moderation
+      title: Föderation
+      total_blocked_by_us: Von uns gesperrt
+      total_followed_by_them: Gefolgt von denen
+      total_followed_by_us: Gefolgt von uns
+      total_reported: Beschwerdemeldungen über sie
+      total_storage: Medienanhänge
     invites:
+      deactivate_all: Alle deaktivieren
       filter:
         all: Alle
         available: Verfügbar
         expired: Ausgelaufen
         title: Filter
       title: Einladungen
+    relays:
+      add_new: Neues Relay hinzufügen
+      delete: Löschen
+      description_html: Ein <strong>Föderierungsrelay</strong> ist ein vermittelnder Server, der eine große Anzahl öffentlicher Beiträge zwischen Servern austauscht, die es abonnieren und zu ihm veröffentlichen.<strong> Es kann kleinen und mittleren Servern dabei helfen, Inhalte des Fediverse zu entdecken</strong>, was andernfalls das manuelle Folgen anderer Leute auf entfernten Servern durch lokale Nutzer erfordern würde.
+      disable: Ausschalten
+      disabled: Ausgeschaltet
+      enable: Einschalten
+      enable_hint: Sobald aktiviert wird dein Server alle öffentlichen Beiträge dieses Relays abonnieren und wird alle öffentlichen Beiträge dieses Servers an es senden.
+      enabled: Eingeschaltet
+      inbox_url: Relay-URL
+      pending: Warte auf Zustimmung des Relays
+      save_and_enable: Speichern und aktivieren
+      setup: Relayverbindung einrichten
+      status: Status
+      title: Relays
     report_notes:
       created_msg: Meldungs-Kommentar erfolgreich erstellt!
       destroyed_msg: Meldungs-Kommentar erfolgreich gelöscht!
@@ -275,7 +353,6 @@ de:
       comment:
         none: Kein
       created_at: Gemeldet
-      id: ID
       mark_as_resolved: Als gelöst markieren
       mark_as_unresolved: Als ungelöst markieren
       notes:
@@ -286,20 +363,15 @@ de:
         placeholder: Beschreibe, welche Maßnahmen ergriffen wurden oder irgendwelche andere Neuigkeiten…
       reopen: Meldung wieder öffnen
       report: 'Meldung #%{id}'
-      report_contents: Inhalt
       reported_account: Gemeldetes Konto
       reported_by: Gemeldet von
       resolved: Gelöst
       resolved_msg: Meldung erfolgreich gelöst!
-      silence_account: Konto stummschalten
       status: Status
-      suspend_account: Konto sperren
-      target: Ziel
       title: Meldungen
       unassign: Zuweisung entfernen
       unresolved: Ungelöst
       updated_at: Aktualisiert
-      view: Ansehen
     settings:
       activity_api_enabled:
         desc_html: Anzahl der lokal geposteten Beiträge, aktiven Nutzern und neuen Registrierungen in wöchentlichen Zusammenfassungen
@@ -310,12 +382,24 @@ de:
       contact_information:
         email: Öffentliche E-Mail-Adresse
         username: Profilname für die Kontaktaufnahme
+      custom_css:
+        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
+      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
+      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
+      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
@@ -336,11 +420,14 @@ de:
         desc_html: Zeige Mitarbeiter-Badge auf Benutzerseite
         title: Zeige Mitarbeiter-Badge
       site_description:
-        desc_html: Wird als Absatz auf der Frontseite angezeigt und als Meta-Tag benutzt. Du kannst HTML-Tags benutzen, insbesondere <code>&lt;a&gt;</code> und <code>&lt;em&gt;</code>.
+        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
       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
+      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
       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
@@ -362,6 +449,7 @@ de:
       media:
         title: Medien
       no_media: Keine Medien
+      no_status_selected: Keine Beiträge wurden verändert, weil keine ausgewählt wurden
       title: Beiträge des Kontos
       with_media: Mit Medien
     subscriptions:
@@ -371,7 +459,21 @@ de:
       last_delivery: Letzte Zustellung
       title: WebSub
       topic: Thema
+    tags:
+      accounts: Konten
+      hidden: Versteckt
+      hide: Vor Verzeichnis verstecken
+      name: Hashtag
+      title: Hashtags
+      unhide: Zeige in Verzeichnis
+      visible: Sichtbar
     title: Administration
+    warning_presets:
+      add_new: Neu hinzufügen
+      delete: Löschen
+      edit: Bearbeiten
+      edit_preset: Warnungsvorlage bearbeiten
+      title: Warnungsvorlagen verwalten
   admin_mailer:
     new_report:
       body: "%{reporter} hat %{target} gemeldet"
@@ -393,7 +495,7 @@ 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 Regeln, die <a href="%{rules_path}">auf dieser Instanz gelten</a> und der <a href="%{terms_path}">Datenschutzerklärung</a> einverstanden.
+    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.
     change_password: Passwort
     confirm_email: E-Mail bestätigen
     delete_account: Konto löschen
@@ -403,8 +505,8 @@ de:
     invalid_reset_password_token: Das Token zum Zurücksetzen des Passworts ist ungültig oder abgelaufen. Bitte fordere ein neues an.
     login: Anmelden
     logout: Abmelden
-    migrate_account: Ziehe zu einem anderen Account um
-    migrate_account_html: Wenn du es wünschst diesen Account zu einem anderen umzuziehen, dann kannst du <a href="%{path}">es hier einstellen</a>.
+    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:
@@ -418,7 +520,7 @@ de:
     set_new_password: Neues Passwort setzen
   authorize_follow:
     already_following: Du folgst diesem Konto bereits
-    error: Das Profil konnte nicht geladen werden
+    error: Das Remote-Konto konnte nicht geladen werden
     follow: Folgen
     follow_request: 'Du hast eine Folgeanfrage gesendet an:'
     following: 'Erfolg! Du folgst nun:'
@@ -449,6 +551,16 @@ de:
     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_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
+    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:
+      one: "%{count} Person"
+      other: "%{count} Leute"
   errors:
     '403': Dir fehlt die Befugnis, diese Seite sehen zu können.
     '404': Diese Seite existiert nicht.
@@ -460,18 +572,20 @@ de:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">nativen Mastodon-Anwendungen</a> für deine Plattform probieren.
+    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.
   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 neues Archiv anfordern.
+      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.
       in_progress: Stelle dein Archiv zusammen...
       request: Dein Archiv anfragen
       size: Größe
     blocks: Du hast blockiert
     csv: CSV
+    domain_blocks: Domainblockaden
     follows: Du folgst
+    lists: Listen
     mutes: Du hast stummgeschaltet
     storage: Medienspeicher
   filters:
@@ -502,9 +616,13 @@ de:
     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:
     changes_saved_msg: Änderungen gespeichert!
-    powered_by: angetrieben von %{link}
+    copy: Kopieren
     save_changes: Änderungen speichern
     validation_errors:
       one: Etwas ist noch nicht ganz richtig! Bitte korrigiere den Fehler
@@ -539,9 +657,7 @@ de:
     table:
       expires_at: Läuft ab
       uses: Verwendungen
-    title: Leute Einladen
-  landing_strip_html: "<strong>%{name}</strong> hat ein Profil auf %{link_to_root_path}. Du kannst folgen oder interagieren, sofern du ein Konto irgendwo im Fediversum hast."
-  landing_strip_signup_html: Wenn nicht, kannst du dich <a href="%{sign_up_path}">hier anmelden</a>.
+    title: Leute einladen
   lists:
     errors:
       limit: Du hast die maximale Anzahl an Listen erreicht
@@ -550,10 +666,10 @@ de:
       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
   migrations:
-    acct: benutzername@domain des neuen Accounts
+    acct: benutzername@domain des neuen Kontos
     currently_redirecting: 'Deine Profilweiterleitung wurde gesetzt auf:'
     proceed: Speichern
-    updated_msg: Deine Account-Migrationseinstellungen wurden erfolgreich aktualisiert!
+    updated_msg: Deine Konto-Migrationseinstellungen wurden erfolgreich aktualisiert!
   moderation:
     title: Moderation
   notification_mailer:
@@ -615,13 +731,28 @@ de:
   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
-    no_account_html: Noch keinen Account? Du kannst dich <a href='%{sign_up_path}' target='_blank'>hier anmelden</a>
+    no_account_html: Noch kein Konto? Du kannst dich <a href='%{sign_up_path}' target='_blank'>hier anmelden</a>
     proceed: Weiter
     prompt: 'Du wirst dieser Person folgen:'
+    reason_html: "<strong>Warum ist dieser Schritt erforderlich?</strong><code>%{instance}</code> ist möglicherweise nicht der Server auf dem du registriert bist, also müssen wir dich erst auf deinen Heimserver weiterleiten."
+  remote_interaction:
+    favourite:
+      proceed: Fortfahren zum Favorisieren
+      prompt: 'Du möchtest diesen Beitrag favorisieren:'
+    reblog:
+      proceed: Fortfahren zum Teilen
+      prompt: 'Du möchtest diesen Beitrag teilen:'
+    reply:
+      proceed: Fortfahren zum Antworten
+      prompt: 'Du möchtest auf diesen Beitrag antworten:'
   remote_unfollow:
     error: Fehler
     title: Titel
     unfollowed: Entfolgt
+  scheduled_statuses:
+    over_daily_limit: Du hast das Limit für geplante Beiträge, dass %{limit} beträgt, für heute erreicht
+    over_total_limit: Du hast das Limit für geplante Beiträge, dass %{limit} beträgt, erreicht
+    too_soon: Das geplante Datum muss in der Zukunft liegen
   sessions:
     activity: Letzte Aktivität
     browser: Browser
@@ -645,7 +776,7 @@ de:
       weibo: Weibo
     current_session: Aktuelle Sitzung
     description: "%{browser} auf %{platform}"
-    explanation: Dies sind die Webbrowser, die derzeit in dein Mastodon-Konto eingeloggt sind.
+    explanation: Dies sind die Webbrowser, die derzeit in deinem Mastodon-Konto eingeloggt sind.
     ip: IP-Adresse
     platforms:
       adobe_air: Adobe Air
@@ -672,7 +803,7 @@ de:
     export: Datenexport
     followers: Autorisierte Folgende
     import: Datenimport
-    migrate: Account-Umzug
+    migrate: Konto-Umzug
     notifications: Benachrichtigungen
     preferences: Einstellungen
     settings: Einstellungen
@@ -701,6 +832,7 @@ de:
       private: Du kannst nur öffentliche Beiträge anheften
       reblog: Du kannst keine geteilten Beiträge anheften
     show_more: Mehr anzeigen
+    sign_in_to_participate: Melde dich an, um an der Konversation teilzuhaben
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Nur Folgende
@@ -710,11 +842,93 @@ de:
       unlisted: Nicht gelistet
       unlisted_long: Für alle sichtbar, aber nicht in öffentlichen Zeitleisten aufgelistet
   stream_entries:
-    click_to_show: Klicken, um zu zeigen
     pinned: Angehefteter Beitrag
     reblogged: teilte
-    sensitive_content: Heikle Inhalte
+    sensitive_content: Sensible 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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Für was verwenden wir deine Informationen?</h3>
+
+      <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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">Wie beschützen wir deine Informationen?</h3>
+
+      <p>Wir implementieren eine Reihe von Sicherheitsmaßnahmen, um die Sicherheit deiner persönlichen Information sicherzustellen, wenn du persönliche Informationen eingibst, übermittelst oder auf sie zugreifst. Neben anderen Dingen, wird sowohl deine Browsersitzung, als auch der Datenverkehr zwischen deinen Anwendungen und der Programmierschnittstelle (API) mit SSL gesichert, dein Passwort wird mit einem starken Einwegalgorithmus gehasht. Du kannst Zwei-Faktor-Authentifizierung aktivieren, um den Zugriff auf dein Konto zusätzlich abzusichern.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">Was ist unsere Datenspeicherungsrichtlinie?</h3>
+
+      <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>
+      </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>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Verwenden wir Cookies?</h3>
+
+      <p>Ja. Cookies sind kleine Dateien, die eine Webseite oder ihr Serviceanbieter über deinen Webbrowser (sofern er es erlaubt) auf die Festplatte deines Computers überträgt. Diese Cookies ermöglichen es der Seite deinen Browser wiederzuerkennen und, sofern du ein registriertes Konto hast, diesen mit deinem registrierten Konto zu verknüpfen.</p>
+
+      <p>Wir verwenden Cookies, um deine Einstellungen zu verstehen und für zukünftige Besuche zu speichern.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Offenbaren wir Informationen an Dritte?</h3>
+
+      <p>Wir verkaufen nicht, handeln nicht mit oder übertragen deine persönlich identifizierbaren Informationen nicht an Dritte. Dies beinhaltet nicht Dritte, die vertrauenswürdig sind und uns beim Betreiben unserer Seite, Leiten unseres Geschäftes oder dabei, die Dienste für dich bereitzustellen, unterstützen, sofern diese Dritte zustimmen, diese Informationen vertraulich zu halten. Wir können auch Informationen freigeben, wenn wir glauben, dass Freigabe angemessen ist, um dem Gesetz zu entsprechen, unsere Seitenrichtlinien durchzusetzen oder unsere Rechte, Eigentum und/oder Sicherheit oder die anderer zu beschützen.</p>
+
+      <p>Dein öffentlicher Inhalt kann durch andere Server im Netzwerk heruntergeladen werden. Deine öffentlichen und "Nur Folgende"-Beiträge werden an die Server ausgeliefert, bei denen sich deine Folgenden befinden und direkte Nachrichten werden an die Server des Empfängers ausgeliefert, falls diese Folgenden oder Empfänger sich auf einem anderen Server als diesen befinden.</p>
+
+      <p>Wenn du eine Anwendung autorisierst, dein Konto zu benutzen, kann diese – abhängig von den von dir genehmigten Befugnissen – auf deine öffentlichen Profilinformationen, deine Folgt- und Folgende-Liste, deine Listen, alle deine Beiträge und deine Favoriten zugreifen. Anwendungen können nie auf deine E-Mail-Adresse oder dein Passwort zugreifen</p>
+
+      <hr class="spacer" />
+
+      <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 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>
+
+      <p>Gesetzesvorschriften können unterschiedlich sein, wenn sich dieser Server in anderer Gerichtsbarkeit befindet.</p>
+
+      <hr class="spacer" />
+
+      <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>Dies ist eine Übersetzung, Irrtümer und Übersetzungsfehler vorbehalten. Im Zweifelsfall gilt die englische Originalversion.</p>
+
+      <p>Dieses Dokument ist CC-BY-SA. Es wurde zuletzt aktualisiert am 7. März 2018.</p>
+
+      <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
@@ -723,6 +937,7 @@ de:
   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.
@@ -736,17 +951,33 @@ de:
     manual_instructions: 'Wenn du den QR-Code nicht einlesen kannst und ihn manuell eingeben musst, ist hier das Klartext-Geheimnis:'
     recovery_codes: Wiederherstellungs-Codes sichern
     recovery_codes_regenerated: Wiederherstellungscodes erfolgreich neu generiert
-    recovery_instructions_html: Wenn du den Zugang zu deinem Telefon verlieren solltest, kannst du einen untenstehenden Wiederherstellungscodes benutzen, um wieder auf dein Konto zugreifen zu können. <strong>Bewahre die Wiederherstellungscodes gut auf.</strong> Du könntest sie beispielsweise ausdrucken und bei deinen restlichen wichtigen Dokumenten aufbewahren.
+    recovery_instructions_html: Wenn du den Zugang zu deinem Telefon verlieren solltest, kannst du einen untenstehenden Wiederherstellungscode benutzen, um wieder auf dein Konto zugreifen zu können. <strong>Bewahre die Wiederherstellungscodes gut auf.</strong> Du könntest sie beispielsweise ausdrucken und bei deinen restlichen wichtigen Dokumenten aufbewahren.
     setup: Einrichten
     wrong_code: Der eingegebene Code war ungültig! Stimmen Serverzeit und Gerätezeit?
   user_mailer:
     backup_ready:
-      explanation: Du hast ein vollständiges Backup von deinem Mastodon-Account angefragt. Es kann jetzt heruntergeladen werden!
+      explanation: Du hast ein vollständiges Backup von deinem Mastodon-Konto angefragt. Es kann jetzt heruntergeladen werden!
       subject: Dein Archiv ist bereit zum Download
       title: Archiv-Download
+    warning:
+      explanation:
+        disable: Solange dein Konto eingefroren ist, sind deine Benutzerdaten intakt; aber du kannst nichts tun, bis dein Konto entsperrt wurde.
+        silence: Solange dein Konto limitiert ist, können nur die Leute, die dir bereits folgen, deine Beiträge auf dem Server sehen und es könnte sein, dass du von verschiedenen öffentlichen Listungen ausgeschlossen wirst. Andererseits können andere dir manuell folgen.
+        suspend: Dein Konto wurde gesperrt und alle deine Beiträge und hochgeladenen Medien wurden unwiderruflich vom Server und anderen Servern, bei denen du Folgende hattest, gelöscht.
+      review_server_policies: Serverrichtlinien ansehen
+      subject:
+        disable: Dein Konto %{acct} wurde eingefroren
+        none: Warnung für %{acct}
+        silence: Dein Konto %{acct} wurde limitiert
+        suspend: Dein Konto %{acct} wurde gesperrt
+      title:
+        disable: Konto eingefroren
+        none: Warnung
+        silence: Konto limitiert
+        suspend: Konto gesperrt
     welcome:
       edit_profile_action: Profil einstellen
-      edit_profile_step: Du kannst dein Profil anpassen, indem du einen Avatar oder ein Titelbild hochlädst oder deinen Anzeigenamen änderst und mehr. Wenn du deine Follower vorher überprüfen möchtest, bevor sie dir folgen können, dann kannst du dein Profil sperren.
+      edit_profile_step: Du kannst dein Profil anpassen, indem du einen Avatar oder ein Titelbild hochlädst oder deinen Anzeigenamen änderst und mehr. Wenn du deine Folgenden vorher überprüfen möchtest, bevor sie dir folgen können, dann kannst du dein Profil sperren.
       explanation: Hier sind ein paar Tipps, um loszulegen
       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.'
@@ -755,7 +986,6 @@ de:
       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
-      tip_bridge_html: Wenn du gerade von Twitter kommst, dann kannst du deine Freunde auf Mastodon mithilfe der <a href="%{bridge_url}">Bridge-App</a> finden. Es funktioniert aber auch nur, wenn diese die Bridge-App vorher verwendet haben!
       tip_federated_timeline: Die föderierte Zeitleiste ist die sehr große Ansicht vom Mastodon-Netzwerk. Sie enthält aber auch nur Leute, denen du und deine Nachbarn folgen, sie ist also nicht komplett.
       tip_following: Du folgst standardmäßig deinen Server-Admin(s). Um mehr interessante Leute zu finden, kannst du die lokale oder öffentliche Zeitleiste durchsuchen.
       tip_local_timeline: Die lokale Zeitleiste ist eine Ansicht aller Leute auf %{instance}. Diese sind deine Nachbarn!
@@ -763,8 +993,12 @@ de:
       tips: Tipps
       title: Willkommen an Bord, %{name}!
   users:
+    follow_limit_reached: Du kannst nicht mehr als %{limit} Leuten folgen
     invalid_email: Ungültige E-Mail-Adresse
     invalid_otp_token: Ungültiger Zwei-Faktor-Authentisierungs-Code
-    otp_lost_help_html: Wenn Sie zu beidem keinen Zugriff mehr haben, kontaktieren sie %{email}
+    otp_lost_help_html: Wenn Du beides nicht mehr weißt, melde Dich bei uns unter der E-Mailadresse %{email}
     seamless_external_login: Du bist angemeldet über einen Drittanbieter-Dienst, weswegen Passwort- und E-Maileinstellungen nicht verfügbar sind.
     signed_in_as: 'Angemeldet als:'
+  verification:
+    explanation_html: 'Du kannst <strong>bestätigen, dass die Links in deinen Profil-Metadaten dir gehören</strong>. Dafür muss die verlinkte Website einen Link zurück auf dein Mastodon-Profil enthalten. Dieser Link <strong>muss</strong> ein <code>rel="me"</code>-Attribut enthalten. Der Linktext ist dabei egal. Hier ist ein Beispiel:'
+    verification: Verifizierung
diff --git a/config/locales/devise.ar.yml b/config/locales/devise.ar.yml
index cadc4daa879ada6ee67f2b0faf722dbcf8bb3d68..927eeee5a10c886cc501bda5f612b289ea784956 100644
--- a/config/locales/devise.ar.yml
+++ b/config/locales/devise.ar.yml
@@ -18,6 +18,7 @@ ar:
     mailer:
       confirmation_instructions:
         action: للتحقق من عنوان البريد الإلكتروني
+        action_with_app: تأكيد ثم العودة إلى %{app}
         explanation: لقد قمت بإنشاء حساب على %{host} بواسطة عنوان البريد الإلكتروني الحالي. إنك على بعد خطوات قليلة من تفعليه. إن لم تكن من طلب ذلك، يرجى ألّا تولي إهتماما بهذه الرسالة.
         extra_html: ندعوك إلى الإطلاع على <a href="%{terms_path}">القواعد الخاصة بمثيل الخادوم هذا</a> and <a href="%{policy_path}">و شروط الخدمة الخاصة بنا</a>.
         subject: 'ماستدون : تعليمات التأكيد لمثيل الخادوم  %{instance}'
@@ -78,5 +79,9 @@ ar:
       not_found: لا يوجد
       not_locked: ليس مقفلاً
       not_saved:
-        one: 'خطأ واحد منَعَ %{resource} مِن القيام بالإحتفاظ :'
-        other: "%{count} أخطاء منعت %{resource} مِن القيام بالإحتفاظ :"
+        few: "%{count} أخطاء منعت هذا %{resource} من الحفظ:"
+        many: "%{count} أخطاء منعت هذا %{resource} من الحفظ:"
+        one: 'خطأ واحد منع هذا %{resource} من الحفظ:'
+        other: "%{count} أخطاء منعت هذا %{resource} من الحفظ:"
+        two: 'أخطاء منعت هذا %{resource} من الحفظ:'
+        zero: 'أخطاء منعت هذا %{resource} من الحفظ:'
diff --git a/config/locales/devise.ast.yml b/config/locales/devise.ast.yml
new file mode 100644
index 0000000000000000000000000000000000000000..49b0c8daf4d133d9f0c3a6e2f7b5adff56308e4e
--- /dev/null
+++ b/config/locales/devise.ast.yml
@@ -0,0 +1,30 @@
+---
+ast:
+  devise:
+    failure:
+      already_authenticated: Yá aniciesti sesión.
+      inactive: Entá nun s'activó la cuenta.
+      last_attempt: Tienes un intentu más enantes de bloquiar la cuenta.
+      locked: La cuenta ta bloquiada.
+      timeout: La sesión caducó. Volvi aniciar sesión pa siguir, por favor.
+      unauthenticated: Precises aniciar sesión o rexistrate enantes de siguir.
+    mailer:
+      confirmation_instructions:
+        explanation: Creesti una cuenta en %{host} con esta direición de corréu. Tas a un clic d'activala. Si nun fuisti tu, inora esti corréu.
+      email_changed:
+        title: Direición de corréu nueva
+      reset_password_instructions:
+        explanation: Solicitesti una contraseña nueva pa la cuenta.
+        extra: Si nun solicitesti esto, inora esti corréu. La contraseña nun va camudar hasta que nun accedas al enllaz d'enriba y crees una nueva.
+    registrations:
+      signed_up: "¡Afáyate! Rexistréstite con ésitu."
+      signed_up_but_unconfirmed: Unvióse un mensaxe de confirmación a la direición de corréu. Sigui l'enllaz p'activar la cuenta. Comprueba la carpeta Puxarra si nun recibiesti esti corréu, por favor.
+      updated: La cuenta anovóse con ésitu.
+    unlocks:
+      send_instructions: Nunos minutos vas recibir un corréu coles instrucciones pa cómo desbloquiar la cuenta. Comprueba la carpeta Puxarra si nun lu recibiesti.
+      send_paranoid_instructions: Si esiste la cuenta, nun momentu vas recibir un corréu coles instrucciones pa cómo desbloquiala. Comprueba la carpeta Puxarra si nun recibiesti esti corréu.
+      unlocked: La cuenta desbloquióse con ésitu. Anicia sesión pa siguir, por favor.
+  errors:
+    messages:
+      already_confirmed: yá se confirmó, volvi aniciar sesión
+      not_found: nun s'alcontró
diff --git a/config/locales/devise.bg.yml b/config/locales/devise.bg.yml
index 8e1ba6eb480b5de2e06ee75b3153bb6c8211d9c7..3c04af81bbb6be9a5f018bf2c70d49aadae9c0d5 100644
--- a/config/locales/devise.bg.yml
+++ b/config/locales/devise.bg.yml
@@ -8,16 +8,16 @@ bg:
     failure:
       already_authenticated: Вече си вътре в профила си.
       inactive: Профилът ти все още не е активиран.
-      invalid: Невалиден имейл адрес или парола.
+      invalid: Невалиден %{authentication_keys}.
       last_attempt: Разполагаш с още един опит преди профилът ти да бъде заключен.
       locked: Профилът ти е заключен.
-      not_found_in_database: Невалидни стойности за %{authentication_keys} или парола.
+      not_found_in_database: Невалиден %{authentication_keys}.
       timeout: Сесията ти изтече, моля влез отново, за да продължиш.
       unauthenticated: Преди да продължиш, трябва да влезеш в профила си или да се регистрираш.
       unconfirmed: Преди да продължиш, трябва да потвърдиш регистрацията си.
     mailer:
       confirmation_instructions:
-        subject: 'Mastodon: Инструкции за потвърждаване'
+        subject: 'Mastodon: Инструкции за потвърждаване %{instance}'
       password_change:
         subject: 'Mastodon: Паролата е променена'
       reset_password_instructions:
diff --git a/config/locales/devise.ca.yml b/config/locales/devise.ca.yml
index 808a5dd0a8ac85929966c356b6ea533cf8690c73..c41a218e14fa860852db4d90005b8c8195bf4f8d 100644
--- a/config/locales/devise.ca.yml
+++ b/config/locales/devise.ca.yml
@@ -18,9 +18,10 @@ ca:
     mailer:
       confirmation_instructions:
         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>.
-        subject: 'Mastodon: Instruccions de confirmació'
+        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:'
diff --git a/config/locales/devise.co.yml b/config/locales/devise.co.yml
index 2471f857beb354b934b5ac09302da2339975fdbd..108a4ef11e2145eba8f578aa270ab6e944d7df4f 100644
--- a/config/locales/devise.co.yml
+++ b/config/locales/devise.co.yml
@@ -18,6 +18,7 @@ co:
     mailer:
       confirmation_instructions:
         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>.
         subject: 'Mastodon: Istruzzione di cunfirmazione per %{instance}'
@@ -55,7 +56,7 @@ co:
       updated: A vostra chjave d’accessu hè stata cambiata, è site cunnettatu·a.
       updated_not_active: A vostra chjave d’accessu hè stata cambiata.
     registrations:
-      destroyed: U vostru contu hè statu sguassatu. Avvedeci!
+      destroyed: Avvedeci! U vostru contu hè statu sguassatu. Speremu di vi rivede da prestu.
       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.
diff --git a/config/locales/devise.cs.yml b/config/locales/devise.cs.yml
index adaa40835cfff5838df111898fe72b117dbebe34..850ff1fe822f5236b775bdab4b697107df3e7b88 100644
--- a/config/locales/devise.cs.yml
+++ b/config/locales/devise.cs.yml
@@ -8,3 +8,77 @@ cs:
     failure:
       already_authenticated: Již jste přihlášen/a.
       inactive: Váš účet ještě není aktivován.
+      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.
+      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.
+    mailer:
+      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>.
+        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.
+        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.
+        subject: 'Mastodon: Heslo bylo změněno'
+        title: Heslo bylo změněno
+      reconfirmation_instructions:
+        explanation: Potvrďte novou adresu pro změnu e-mailu.
+        extra: Pokud jste tuto změnu nevyžádal/a vy, prosím ignorujte tento e-mail. E-mailová adresa nebude změněna, dokud nepřejdete na výše uvedenou adresu.
+        subject: 'Mastodon: Potvrďte e-mail pro %{instance}'
+        title: Ověřit e-mailovou adresu
+      reset_password_instructions:
+        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'
+        title: Obnovení hesla
+      unlock_instructions:
+        subject: 'Mastodon: Instrukce pro odemčení účtu'
+    omniauth_callbacks:
+      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.
+      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:
+      destroyed: Sbohem! Váš účet byl úspěšně zrušen. Doufáme, že vás opět brzy uvidíme.
+      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.
+      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.
+      unlocked: Váš účet byl úspěšně odemčen. Pro pokračování se prosím přihlaste.
+  errors:
+    messages:
+      already_confirmed: byl již potvrzen, prosím zkuste se přihlásit
+      confirmation_period_expired: musí být potvrzen do %{period}, prosím vyžádejte si nový
+      expired: vypršel, prosím vyžádejte si nový
+      not_found: nenalezen
+      not_locked: nebyl uzamčen
+      not_saved:
+        few: "%{count} chyby zabránily 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
new file mode 100644
index 0000000000000000000000000000000000000000..7d96e57f9b70035d6ba5d78ec85e0d18470f81c9
--- /dev/null
+++ b/config/locales/devise.cy.yml
@@ -0,0 +1,80 @@
+---
+cy:
+  devise:
+    confirmations:
+      confirmed: Mae eich cyfeiriad e-bost wedi ei gadarnhau yn llwyddiannus.
+      send_instructions: Byddwch yn derbyn e-bost a chyfarwyddiadau am sut i gadarnhau eich cyfeiriad e-bost mewn rhai munudau. Os na dderbynioch chi'r e-bost hwn, edrychwch yn eich ffolder sbam os gwelwch yn dda.
+      send_paranoid_instructions: Os yw eich cyfeiriad e-bost yn bodoli yn ein bas data, byddwch yn derbyn e-bost a chyfarwyddiadau am sut i gadarnhau eich cyfeiriad ebost mewn rhai munudau. Os na dderbynioch chi'r e-bost hwn, edrychwch yn eich ffolder sbam os gwelwch yn dda.
+    failure:
+      already_authenticated: Yr ydych wedi mewngofnodi yn barod.
+      inactive: Nid yw eich cyfrif yn weithredol eto.
+      invalid: "%{authentication_keys} neu gyfrinair annilys."
+      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."
+      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
+        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.
+        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
+      email_changed:
+        explanation: 'Mae''r cyfeiriad e-bost ar gyfer eich cyfrif yn cael ei newid i:'
+        extra: Os na wnaethoch chi newid eich e-bost, mae'n debygol fod rhywun wedi cael mynediad i'ch cyfrif. Newidwch eich cyfrinair yn syth os gwelwch yn dda neu cysylltwch a gweinydd yr achos os ydych wedi'ch cloi allan o'ch cyfrif.
+        subject: 'Mastodon: Newidwyd e-bost'
+        title: Cyfeiriad e-bost newydd
+      password_change:
+        explanation: Newidwyd cyfrinair eich cyfrif.
+        extra: Os na wnaethoch chi newid eich e-bost, mae'n debygol fod rhywun wedi cael mynediad i'ch cyfrif. Newidwch eich cyfrinair yn syth os gwelwch yn dda neu cysylltwch a gweinydd yr achos os ydych wedi'ch cloi allan o'ch cyfrif.
+        subject: 'Mastodon: Newidwyd Cyfrinair'
+        title: Newidwyd cyfrinair
+      reconfirmation_instructions:
+        explanation: Cadarnhewch y cyferiad newydd i newid eich e-bost.
+        extra: Os nad chi wnaeth y newid hwn, anwybyddwch yr e-bost hwn os gwelwch yn dda. Ni fydd y cyfeiriad e-bost ar gyfer y cyfrif Mastodon yn newid nes eich bod yn mynd at y ddolen uchod.
+        subject: 'Mastodon: Cadarnhewch e-bost i %{instance}'
+        title: Gwirio cyfeiriad e-bost
+      reset_password_instructions:
+        action: Newid cyfrinair
+        explanation: Gofynnoch am gyfrinair newydd i'ch cyfrif.
+        extra: Os na wnaethoch gais am hyn, anwybyddwch yr e-bost hwn os gwelwch yn dda. Ni fydd eich cyfrinair yn newid nes i chi fynd at y ddolen uchod a chreu un newydd.
+        subject: 'Mastodon: Ailosod cyfarwyddiadau cyfrinair'
+        title: Ailosod cyfrinair
+      unlock_instructions:
+        subject: 'Mastodon: Cyfarwyddiadau datgloi'
+    omniauth_callbacks:
+      failure: Methu eich dilysu o %{kind} oherwydd "%{reason}".
+      success: Dilyswyd yn llwyddiannus o gyfrif %{kind}.
+    passwords:
+      no_token: Nid oes modd cael mynediad i'r dudalen hon heb ddod drwy e-bost ailosod cyfrinair. Os ydych yn dod o e-bost ailosod cyfrinair, gwnewch yn siŵr y defnyddioch chi'r URL a ddarparwyd yn ei gyfanrwydd.
+      send_instructions: Os yw eich cyfeiriad e-bost yn bresennol yn ein bas data, mi fyddwch yn derbyn dolen yn eich blwch e-bost ymhen cwpl o funudau. Os nad ydych yn derbyn yr e-bost hwn, edrychwch yn eich ffolder spam os gwelwch yn dda.
+      send_paranoid_instructions: Os yw eich cyfeiriad e-bost yn bresennol yn ein bas data, mi fyddwch yn derbyn dolen yn eich blwch e-bost ymhen cwpl o funudau. Os nad ydych yn derbyn yr e-bost hwn, edrychwch yn eich ffolder spam os gwelwch yn dda.
+      updated: Mae eich cyfrinair wedi ei newid yn llwyddiannus. Yr ydych wedi mewngofnodi.
+      updated_not_active: Mae eich cyfrinair wedi ei newid yn llwyddiannus.
+    registrations:
+      destroyed: Hwyl fawr! Mae eich cyfrif wedi ei ganslo'n llwyddiannus. Gobeithiwn eich gweld chi eto'n fuan.
+      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_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.
+    sessions:
+      already_signed_out: Allgofnodwyd yn llwyddiannus.
+      signed_in: Mewngofnodwyd yn llwyddiannus.
+      signed_out: Allgofnodwyd yn llwyddiannus.
+    unlocks:
+      send_instructions: Mi fyddwch yn derbyn e-bost a chyfarwyddiadau ynghylch sut i ddatgloi eich cyfrif ymhen cwpl o funudau. Edrychwch yn eich ffolder sbam os na dderbynioch chi'r e-bost hwn os gwelwch yn dda.
+      send_paranoid_instructions: Os yw eich cyfrif yn bodoli, mi fyddwch yn derbyn e-bost a cyfarwyddiadau o sut i ddatgloi eich cyfrif ymhen cwpl o funudau. Edrychwch yn eich ffolder sbam os na dderbynioch chi'r e-bost hwn os gwelwch yn dda.
+      unlocked: Mae eich cyfrif wedi ei ddatgloi'n llwyddiannus. Mewngofnodwch i barhau.
+  errors:
+    messages:
+      already_confirmed: wedi ei gadarnhau yn barod, ymgeisiwch fewngofnodi
+      confirmation_period_expired: angen ei gadarnhau o fewn %{period}, gwnewch gais am un newydd os gwelwch yn dda
+      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:'
diff --git a/config/locales/devise.da.yml b/config/locales/devise.da.yml
index 7c6ac8b195713ea78370339deaea9b65dada5a06..56ae5183bf396c29357df8125c5dc6d2e899f043 100644
--- a/config/locales/devise.da.yml
+++ b/config/locales/devise.da.yml
@@ -4,6 +4,7 @@ da:
     confirmations:
       confirmed: Din email adresse er blevet succesfuldt bekræftet.
       send_instructions: Du vil modtage en mail med instrukser for hvordan du bekræfter din email adresse om få minutter. Tjek venligst din spam mappe hvis du ikke har modtaget denne email.
+      send_paranoid_instructions: Hvis din email adresse allerede findes i vores database, vil du modtage en email med instrukser for hvordan du bekræfter din email adresse om få minutter. Tjek gerne din spam mappe hvis du ikke modtager denne email.
     failure:
       already_authenticated: Du er allerede logget ind.
       inactive: Din konto er endnu ikke aktiveret.
@@ -17,7 +18,9 @@ da:
     mailer:
       confirmation_instructions:
         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>.
         subject: 'Mastodon: Bekræftelses instrukser for %{instance}'
         title: Bekræft email adresse
       email_changed:
@@ -32,14 +35,33 @@ da:
         title: Kodeordet er blevet ændret
       reconfirmation_instructions:
         explanation: Bekræft den nye adresse for at ændre din email.
+        extra: Hvis denne ændring ikke blev foretaget af dig, ignorer denne email. Email adressen for denne Mastodon konto vil ikke blive ændret før du følger linket foroven.
         subject: 'Mastodon: Bekræft email for %{instance}'
         title: Bekræft email adresse
       reset_password_instructions:
         action: Ændre kodeord
-        explanation: Du anmodede om et nyt kodeord for din konto.
+        explanation: Du anmodede om en ny adgangskode for din konto.
+        extra: Hvis du ikke har anmodet om dette, ignorer denne email. Din adgangskode vil ikke blive ændret før du har fulgt linket foroven og oprettet en ny.
+        subject: 'Mastodon: Instrukser for nulstilling af adgangskode'
         title: Kodeordet er blevet nulstillet
+      unlock_instructions:
+        subject: 'Mastodon: Instruktioner for oplåsning'
+    omniauth_callbacks:
+      failure: Kunne ikke godkende dig fra %{kind} fordi "%{reason}".
+      success: Godkendelse fra %{kind} konto lykkedes.
+    passwords:
+      no_token: Du kan ikke tilgå denne side uden at komme fra en email om nulstilling af adgangskode. Hvis du kommer fra en email om nulstilling af adgangskode, tjek om du brugte det fulde link der blev angivet.
+      send_instructions: Hvis din email adresse allerede findes i vores database, vil du modtage et link til nulstilling af adgangskode til din email adresse om få minutter. Tjek din spam mappe hvis du ikke har modtaget denne email.
+      send_paranoid_instructions: Hvis din email adresse allerede findes i vores database, vil du modtage et link til nulstilling af adgangskode til din email adresse om få minutter. Tjek din spam mappe hvis du ikke har modtaget denne email.
+      updated: Din adgangskode er nu blevet ændret. Du er nu logget ind.
+      updated_not_active: Din adgangskode blev ændret.
     registrations:
+      destroyed: Farvel! Din konto er nu annulleret. Vi håber snart at se dig igen.
       signed_up: Velkommen! Du har nu tilmeldt dig.
+      signed_up_but_inactive: Du har nu oprettet dig. Vi kunne dog ikke logge dig ind da din konto endnu ikke er aktiveret.
+      signed_up_but_locked: Du har nu oprettet dig. Vi kunne dog ikke logge dig ind da din konto er låst.
+      signed_up_but_unconfirmed: En besked med et bekræftelses link er nu blevet sendt til din email adresse. Følg linket for at aktivere din konti. Tjek din spam mappe hvis du ikke har modtaget denne email.
+      update_needs_confirmation: Du har succesfuldt opdateret din konto, men vi er nødt til at bekræfte din email adresse. Tjek venligst din email og følg bekræftelses linket for at bekræfte din nye email adresse. Tjek venligst din spam mappe hvis du ikke har modtaget denne email.
       updated: Din konto er nu blevet opdateret.
     sessions:
       already_signed_out: Du er nu logget ud.
diff --git a/config/locales/devise.de.yml b/config/locales/devise.de.yml
index 0d33af6f1a7622b431eed45b2e937025a10f32ec..fc41c9db51a67a178c4b0a2819c6ed90adf76185 100644
--- a/config/locales/devise.de.yml
+++ b/config/locales/devise.de.yml
@@ -18,6 +18,7 @@ de:
     mailer:
       confirmation_instructions:
         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>.
         subject: 'Mastodon: Bestätigung deines Kontos bei %{instance}'
diff --git a/config/locales/devise.el.yml b/config/locales/devise.el.yml
index 523d1fb88bf7c06fa1fd06e09aed6bfd14a6d4ec..e9725d96b968f6c2f9e06f3e33470566c69b863e 100644
--- a/config/locales/devise.el.yml
+++ b/config/locales/devise.el.yml
@@ -18,6 +18,7 @@ el:
     mailer:
       confirmation_instructions:
         action: Επιβεβαίωσε διεύθυνση email
+        action_with_app: Επιβεβαίωση και επιστροφή στο %{app}
         explanation: Δημιούργησες έναν λογαριασμό στο %{host} με αυτή τη διεύθυνση email. Με ένα κλικ θα τον ενεργοποιήσεις. Αν δεν το έκανες εσύ, παρακαλούμε αγνόησε αυτό το email.
         extra_html: Παρακαλούμε να διαβάσεις <a href="%{terms_path}">του κανόνες αυτού του κόμβου</a> και <a href="%{policy_path}">τους όρους χρήσης της υπηρεσίας μας</a>.
         subject: 'Mastodon: Οδηγίες επιβεβαίωσης για %{instance}'
diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml
index 20938e47b6421b0b0223eadb37fdd1978f5059aa..bd0642b25169809a8ea161321bdae3869795ddeb 100644
--- a/config/locales/devise.en.yml
+++ b/config/locales/devise.en.yml
@@ -18,6 +18,7 @@ en:
     mailer:
       confirmation_instructions:
         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>.
         subject: 'Mastodon: Confirmation instructions for %{instance}'
diff --git a/config/locales/devise.eu.yml b/config/locales/devise.eu.yml
index 8905822a744cb1fd3068eaba594e5688bf736e91..9893f5ba32564701457fd9729f9e63dae7729ed2 100644
--- a/config/locales/devise.eu.yml
+++ b/config/locales/devise.eu.yml
@@ -18,6 +18,7 @@ eu:
     mailer:
       confirmation_instructions:
         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>.
         subject: 'Mastodon: %{instance} instantziaren argibideak baieztapenerako'
diff --git a/config/locales/devise.fr.yml b/config/locales/devise.fr.yml
index 7e10f83b4b257db9f9971715499919a1c2ab8dd0..718b4056e70b95eefaf459c7f8b8caa9942255b7 100644
--- a/config/locales/devise.fr.yml
+++ b/config/locales/devise.fr.yml
@@ -8,39 +8,40 @@ fr:
     failure:
       already_authenticated: Vous êtes déjà connecté⋅e.
       inactive: Votre compte n’est pas encore activé.
-      invalid: Courriel ou mot de passe incorrect.
+      invalid: "%{authentication_keys} invalide."
       last_attempt: Vous avez droit à une tentative avant que votre compte ne soit verrouillé.
       locked: Votre compte est verrouillé.
-      not_found_in_database: Courriel ou mot de passe invalide.
+      not_found_in_database: "%{authentication_keys} invalide."
       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.
     mailer:
       confirmation_instructions:
-        action: Vérifier l'adresse courriel
-        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: S'il vous plaît, consultez également <a href="%{terms_path}"> 1les règles de l'instance</a> 2 et <a href="%{policy_path}">3nos termes de service</a> 4.
+        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}
-        title: Vérifier l'adresse courriel
+        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 de l'instance si vous êtes bloqué hors de votre compte.
+        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.
         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 de l'instance si vous êtes bloqué hors de votre compte.
+        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
         title: Mot de passe modifié
       reconfirmation_instructions:
         explanation: Confirmez la nouvelle adresse pour changer votre courriel.
-        extra: Si ce changement n' a pas été initié par vous, veuillez ignorer ce courriel. L'adresse courriel du compte Mastodon ne changera pas tant que vous n'aurez pas cliqué sur le lien ci-dessus.
-        subject: 'Mastodon : Confirmez l''email pour %{instance}'
-        title: Vérifier l'adresse courriel
+        extra: Si ce changement n’a pas été initié par vous, veuillez ignorer ce courriel. L’adresse courriel du compte Mastodon ne changera pas tant que vous n’aurez pas cliqué sur le lien ci-dessus.
+        subject: 'Mastodon : Confirmez l’adresse pour %{instance}'
+        title: Vérifier l’adresse courriel
       reset_password_instructions:
         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.
+        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
         title: Réinitialisation du mot de passe
       unlock_instructions:
diff --git a/config/locales/devise.gl.yml b/config/locales/devise.gl.yml
index a8fe6a2a5b8f0d1b1fcc91c35d23dc39e405aeb2..9f60747a6a1f43eed850adf5217c75d12deae063 100644
--- a/config/locales/devise.gl.yml
+++ b/config/locales/devise.gl.yml
@@ -18,6 +18,7 @@ gl:
     mailer:
       confirmation_instructions:
         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>.
         subject: 'Mastodon: Instruccións de confirmación para %{instance}'
diff --git a/config/locales/devise.he.yml b/config/locales/devise.he.yml
index 4a2811b1fdbe901b88616be21a17e020865b0bc8..3d8f7fa59b64931bb5a781e97274831f36b5c28b 100644
--- a/config/locales/devise.he.yml
+++ b/config/locales/devise.he.yml
@@ -17,7 +17,7 @@ he:
       unconfirmed: יש לאמת את כתובת הדוא"ל על מנת להמשיך.
     mailer:
       confirmation_instructions:
-        subject: 'מסטודון: הוראות אימות'
+        subject: 'מסטודון: הוראות אימות %{instance}'
       password_change:
         subject: 'מסטודון: הסיסמא שונתה'
       reset_password_instructions:
diff --git a/config/locales/devise.hr.yml b/config/locales/devise.hr.yml
index d578e404f6472f2481c5256c92d9acddc97ce009..2a859054a66ae19a260efc55c156c7acc523e9a4 100644
--- a/config/locales/devise.hr.yml
+++ b/config/locales/devise.hr.yml
@@ -8,7 +8,7 @@ hr:
       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: Nevaljani %{authentication_keys} ili lozinka.
+      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.
@@ -16,7 +16,7 @@ hr:
       unconfirmed: Moraš potvrditi svoju email adresu prije no što nastaviš.
     mailer:
       confirmation_instructions:
-        subject: 'Mastodon: Upute za potvrđivanje'
+        subject: 'Mastodon: Upute za potvrđivanje %{instance}'
       email_changed:
         subject: 'Mastodon: Email adresa je promijenjena'
         title: Nova email adresa
@@ -58,6 +58,4 @@ hr:
       expired: je istekao, zatraži novu
       not_found: nije nađen
       not_locked: nije zaključan
-      not_saved:
-        one: '1 greška je zabranila da ovaj %{resource} bude sačuvan:'
-        other: "%{count} greške su zabranile da ovaj %{resource} bude sačuvan:"
+      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 79ee3b194e97cab811d186f20c9427771027ac53..67baca0167ddb826428fe4de84ed9d093be681cb 100644
--- a/config/locales/devise.hu.yml
+++ b/config/locales/devise.hu.yml
@@ -20,7 +20,7 @@ hu:
         action: Erősítsd meg az e-mail címedet
         explanation: Ezzel az e-mail címmel kezdeményeztek regisztrációt a(z) %{host} oldalon. Csak egy kattintás, és a felhasználói fiókdat aktiváljuk. Ha a regisztrációt nem te kezdeményezted, kérjük tekintsd ezt az e-mailt tárgytalannak.
         extra_html: Kérjük tekintsd át a <a href="%{terms_path}">az instancia szabályzatát</a> és <a href="%{policy_path}">a felhasználási feltételeket</a>.
-        subject: 'Mastodon: Megerősítési lépések'
+        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:'
diff --git a/config/locales/devise.io.yml b/config/locales/devise.io.yml
index 6ba3038bdb00a901215506e96216b0a220e03e85..fce061a651fc9f658e98353a375a373d63b24704 100644
--- a/config/locales/devise.io.yml
+++ b/config/locales/devise.io.yml
@@ -8,16 +8,16 @@ io:
     failure:
       already_authenticated: Tu ya esas enirinta.
       inactive: Tua konto ankore ne konfirmesas.
-      invalid: Nejusta retpost-adreso o pasvorto.
+      invalid: Nejusta %{authentication_keys}.
       last_attempt: Tu ankore povas probar unfoye ante ke tua konto esos extingita.
       locked: Tua konto esas extingita.
-      not_found_in_database: Nejusta retpost-adreso o pasvorto.
+      not_found_in_database: Nejusta %{authentication_keys}.
       timeout: Tua kunsido expiris. Voluntez rienirar por durar.
       unauthenticated: Tu devas enirar o membreskar por durar.
       unconfirmed: Tu devas konfirmar tua konto por durar.
     mailer:
       confirmation_instructions:
-        subject: Instrucioni por konfirmar
+        subject: Instrucioni por konfirmar %{instance}
       password_change:
         subject: Tua pasvorto chanjesis senprobleme.
       reset_password_instructions:
diff --git a/config/locales/devise.it.yml b/config/locales/devise.it.yml
index 0c5d8963c9eb0d5ebd0a03d5816a904cde43387d..30266e46bdd4abbe4db811fb9adf1ffcd2dcbcd2 100644
--- a/config/locales/devise.it.yml
+++ b/config/locales/devise.it.yml
@@ -18,6 +18,7 @@ it:
     mailer:
       confirmation_instructions:
         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>.
         subject: 'Mastodon: Istruzioni di conferma per %{instance}'
diff --git a/config/locales/devise.ja.yml b/config/locales/devise.ja.yml
index 1f6395479ac0f8835cc555b9b8dbf039cf4b3f1f..cae76d49385f5ebca38151d84522b841acf5a4c5 100644
--- a/config/locales/devise.ja.yml
+++ b/config/locales/devise.ja.yml
@@ -18,9 +18,10 @@ ja:
     mailer:
       confirmation_instructions:
         action: メールアドレスの確認
+        action_with_app: 確認し %{app} に戻る
         explanation: このメールアドレスで%{host}にアカウントを作成しました。有効にするまであと一歩です。もし心当たりがない場合、申し訳ありませんがこのメールを無視してください。
         extra_html: また <a href="%{terms_path}">インスタンスのルール</a> と <a href="%{policy_path}">利用規約</a> もお読みください。
-        subject: 'Mastodon: メールアドレスの確認'
+        subject: 'Mastodon: メールアドレスの確認 %{instance}'
         title: メールアドレスの確認
       email_changed:
         explanation: 'アカウントのメールアドレスは以下のように変更されます:'
diff --git a/config/locales/devise.ka.yml b/config/locales/devise.ka.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3267eb22ebdfdf297c2d30c823c5d779f638e635
--- /dev/null
+++ b/config/locales/devise.ka.yml
@@ -0,0 +1,82 @@
+---
+ka:
+  devise:
+    confirmations:
+      confirmed: თქვენი ელ-ფოსტის მისამართი წარმატებით დამოწმდა.
+      send_instructions: თქვენ მიიღებთ ელ-ფოსტას ინსტრუქციებით თუ როგორც დაამოწმოთ თქვენი ელ-ფოსტის მისამართი რამდენიმე წუთში. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
+      send_paranoid_instructions: თუ თქვენი ელ-ფოსტა არსებობს ჩვენს მონაცემთა ბაზაში, თქვენ მიიღებთ ელ-ფოსტას ინსტრუქციებით თუ როგორც დაამოწმოთ თქვენი ელ-ფოსტის მისამართი რამდენიმე წუთში. გთხოვთ შეხედოთ თქვენი სპამის ფოლდერს თუ არ მიიღებთ ამ წერილს.
+    failure:
+      already_authenticated: უკვე შესული ხართ.
+      inactive: თქვენი ანგარიში ჯერ არაა აქტივირებული.
+      invalid: არასწორი %{authentication_keys} ან პაროლი.
+      last_attempt: თქვენი ანგარიშის ჩაკეტვამდე დაგრჩათ კიდევ ერთი მცდელობა.
+      locked: თქვენი ანგარიში ჩაიკეტა.
+      not_found_in_database: არასწორი %{authentication_keys} ან პაროლი.
+      timeout: თქვენს სესიას გაუვიდა ვადა. გთხოვთ შედით ახლიდან რომ გააგრძელოთ.
+      unauthenticated: გაგრძელებამდე საჭიროა შეხვიდეთ ან დარეგისტრირდეთ.
+      unconfirmed: გაგრძელებამდე საჭიროა დაამოწმოთ თქვენი ელ-ფოსტა.
+    mailer:
+      confirmation_instructions:
+        action: დაამოწმეთ ელ-ფოსტის მისამართი
+        explanation: თქვენ ამ ელ-ფოსტის მისამართი ანგარიში შექმენით %{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: 'ვერ მოხდა აუტენტიფიკაცია %{kind}-თან. მიზეზი: "%{reason}".'
+      success: წარმატებით შედგა აუტენტიფიკაცია %{kind} ანგარიშთან.
+    passwords:
+      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: თქვენი ანგარიში წარმატებით განახლდა.
+    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: "%{resource} ვერ დამახსოვრდა ერთი შეცდომის გამო:"
+        other: "%{resource} ვერ დამახსოვრდა %{count} შეცდომის გამო:"
diff --git a/config/locales/devise.nl.yml b/config/locales/devise.nl.yml
index b21798debee5937ea33645612047999408e0f1c8..a768d3c1d2a4429eb87309575608c230c63f80a8 100644
--- a/config/locales/devise.nl.yml
+++ b/config/locales/devise.nl.yml
@@ -8,17 +8,18 @@ nl:
     failure:
       already_authenticated: Je bent al ingelogd.
       inactive: Jouw account is nog niet geactiveerd.
-      invalid: Ongeldig e-mailadres of wachtwoord.
+      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: Ongeldig e-mailadres of wachtwoord.
+      not_found_in_database: "%{authentication_keys} of wachtwoord ongeldig."
       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.
     mailer:
       confirmation_instructions:
         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.
         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}'
@@ -47,8 +48,8 @@ nl:
       unlock_instructions:
         subject: 'Mastodon: Instructies om opschorten account ongedaan te maken'
     omniauth_callbacks:
-      failure: Kon je niet aanmelden met jouw %{kind} account, omdat "%{reason}".
-      success: Successvol aangemeld met jouw %{kind} account.
+      failure: Kon je niet inloggen met jouw %{kind} account, omdat "%{reason}".
+      success: Succesvol met jouw %{kind} account ingelogd.
     passwords:
       no_token: Je kunt deze pagina niet benaderen zonder dat je een e-mail om je wachtwoord opnieuw in te stellen hebt ontvangen.
       send_instructions: Je ontvangt via e-mail instructies hoe je jouw wachtwoord opnieuw moet instellen. Kijk tussen je spam wanneer niks werd ontvangen.
diff --git a/config/locales/devise.no.yml b/config/locales/devise.no.yml
index ca16c6ba504ddbc00143502e48d5c2b647c25c27..222a91aa30ee070d1b3042e67efb83c590d44fe3 100644
--- a/config/locales/devise.no.yml
+++ b/config/locales/devise.no.yml
@@ -20,7 +20,7 @@
         action: Bekreft e-postadresse
         explanation: Du har laget en konto på %{host} med denne e-postadressen. Du er ett klikk unna å aktivere den. Hvis dette ikke var deg, vennligst se bort fra denne e-posten.
         extra_html: Vennligst også sjekk ut <a href="%{terms_path}">instansens regler </a> og <a href="%{policy_path}">våre bruksvilkår</a>.
-        subject: 'Mastodon: Instruksjoner for å bekrefte e-postadresse'
+        subject: 'Mastodon: Instruksjoner for å bekrefte e-postadresse %{instance}'
         title: Bekreft e-postadresse
       email_changed:
         explanation: 'E-postadressen til din konto endres til:'
diff --git a/config/locales/devise.oc.yml b/config/locales/devise.oc.yml
index 06617af3402bc291184cd852e07b9e39cabc8a9b..99809b8585c6ce6f6b0ffd357041ce11838be492 100644
--- a/config/locales/devise.oc.yml
+++ b/config/locales/devise.oc.yml
@@ -8,16 +8,17 @@ oc:
     failure:
       already_authenticated: Sètz ja connectat.
       inactive: Vòstre compte es pas encara activat.
-      invalid: Corrièl o senhal invalid.
+      invalid: "%{authentication_keys} invalida."
       last_attempt: Vos demòra un ensag abans que vòstre compte siasque blocat.
       locked: Vòstre compte es blocat.
-      not_found_in_database: Corrièl o senhal invalid.
+      not_found_in_database: "%{authentication_keys} invalida."
       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.
     mailer:
       confirmation_instructions:
         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>.
         subject: 'Mastodon : consignas de confirmacion per %{instance}'
@@ -50,8 +51,8 @@ oc:
       success: Sètz ben autentificat dempuèi lo compte %{kind}.
     passwords:
       no_token: Podètz pas accedir a aquesta pagina sens venir d’un corriel de reïnicializacion de senhal. S’es lo cas, mercés de verificar qu’avètz ben utilizat l’URL donada de manièra complèta.
-      send_instructions: Recebretz un corrièl amb las consignas per reĩnicializar vòstre senhal dins una estona. Mercés de verificar tanben vòstre dorsièr de corrièls indesirables.
-      send_paranoid_instructions: Se vòstra adreça de corrièl existís dins nòstra basa de donadas, recebretz un ligam per reĩnicializar vòstre senhal dins una estona. Mercés de verificar tanben vòstre dorsièr de corrièls indesirables.
+      send_instructions: Recebretz un corrièl amb las consignas per reïnicializar vòstre senhal dins una estona. Mercés de verificar tanben vòstre dorsièr de corrièls indesirables.
+      send_paranoid_instructions: Se vòstra adreça de corrièl existís dins nòstra basa de donadas, recebretz un ligam per reïnicializar vòstre senhal dins una estona. Mercés de verificar tanben vòstre dorsièr de corrièls indesirables.
       updated: Vòstre senhal es ben estat cambiat. Sètz ara connectat.
       updated_not_active: Vòstre senhal es ben estat cambiat.
     registrations:
diff --git a/config/locales/devise.pl.yml b/config/locales/devise.pl.yml
index 53a4f4552edf80960dc73cd3b2426c0805bc9d5e..57c21437b815afa7de4ac0361c4e2668682ec591 100644
--- a/config/locales/devise.pl.yml
+++ b/config/locales/devise.pl.yml
@@ -6,7 +6,7 @@ pl:
       send_instructions: W ciągu kilku minut otrzymasz wiadomosć e-mail z instrukcją jak potwierdzić Twój adres e-mail. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem.
       send_paranoid_instructions: Jeśli Twój adres e-mail już istnieje w naszej bazie danych, w ciągu kilku minut otrzymasz wiadomość e-mail z instrukcją jak potwierdzić Twój adres e-mail. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem.
     failure:
-      already_authenticated: Jesteś już zalogowany/zalogowana.
+      already_authenticated: Jesteś już zalogowany(-a).
       inactive: Twoje konto nie zostało jeszcze aktywowane.
       invalid: Nieprawidłowy %{authentication_keys} lub hasło.
       last_attempt: Masz jeszcze jedną próbę; Twoje konto zostanie zablokowane jeśli się nie powiedzie.
@@ -18,28 +18,29 @@ pl:
     mailer:
       confirmation_instructions:
         action: Zweryfikuj adres e-mail
-        explanation: Utworzyłeś 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.
+        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>.
-        subject: 'Mastodon: Instrukcje weryfikacji adresu e-mail'
+        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ś 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 isntancji, 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ś 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 instancji, jeżeli nie masz dostępu do konta.
         subject: 'Mastodon: Zmieniono hasło'
         title: Zmieniono hasło
       reconfirmation_instructions:
         explanation: Potwierdź nowy adres aby zmienić e-mail.
-        extra: Jeżeli nie próbowałeś zmienić e-maila, zignoruj tą wiadomość. Adres e-mail przypisany do konta Mastodona nie ulegnie zmianie, jeżeli nie użyjesz powyższego odnośniku.
-        subject: 'Mastodon: Potwierdź adres e-mail na &{instance}'
+        extra: Jeżeli nie próbowałeś(-aś) zmienić e-maila, zignoruj tą wiadomość. Adres e-mail przypisany do konta Mastodona nie ulegnie zmianie, jeżeli nie użyjesz powyższego odnośniku.
+        subject: 'Mastodon: Potwierdź adres e-mail na %{instance}'
         title: Zweryfikuj adres e-mail
       reset_password_instructions:
         action: Zmień hasło
-        explanation: Próbowałeś uzyskać nowe hasło do swojego konta.
+        explanation: Próbowałeś(-aś) uzyskać nowe hasło do swojego konta.
         extra: Jeżeli to nie Ty, zignoruj tą wiadomość. Twoje hasło nie ulegnie zmianie, jeżeli nie wykorzystasz powyższego odnośnika i nie utworzysz nowego hasła.
         subject: 'Mastodon: Instrukcje ustawienia nowego hasła'
         title: Przywracanie hasła
@@ -49,10 +50,10 @@ pl:
       failure: 'Uwierzytelnienie przez %{kind} nie powiodło się, ponieważ: "%{reason}".'
       success: Uwierzytelnienie przez %{kind} powiodło się.
     passwords:
-      no_token: Dostęp do tej strony możliwy jest wyłącznie za pomocą odnośnika z e-maila z instrukcjami ustawienia nowego hasła. Jeśli skorzystałeś/aś z takiego odnośnika, upewnij się, że został wykorzystany/skopiowany cały odnośnik.
+      no_token: Dostęp do tej strony możliwy jest wyłącznie za pomocą odnośnika z e-maila z instrukcjami ustawienia nowego hasła. Jeśli skorzystałeś(-aś) z takiego odnośnika, upewnij się, że został wykorzystany/skopiowany cały odnośnik.
       send_instructions: W ciągu kilku minut otrzymasz wiadomość e-mail z instrukcją ustawienia nowego hasła. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem.
       send_paranoid_instructions: Jeśli Twój adres e-mail już istnieje w naszej bazie danych, w ciągu kilku minut otrzymasz wiadomość e-mail zawierającą odnośnik pozwalający na ustawienie nowego hasła. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem.
-      updated: Twoje hasło zostało zmienione. Jesteś zalogowany/a.
+      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!
@@ -63,9 +64,9 @@ pl:
       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.
     sessions:
-      already_signed_out: Zostałeś/aś wylogowany/a.
-      signed_in: Zostałeś/aś zalogowany/a.
-      signed_out: Zostałeś/aś wylogowany/a.
+      already_signed_out: Zostałeś(-aś) wylogowany(-a).
+      signed_in: Zostałeś(-aś) zalogowany(-a).
+      signed_out: Zostałeś(-aś) wylogowany(-a).
     unlocks:
       send_instructions: W ciągu kilku minut otrzymasz wiadomość e-mail z instrukcjami odblokowania konta. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem.
       send_paranoid_instructions: Jeśli Twoje konto istnieje, instrukcje odblokowania go otrzymasz w wiadomości e-mail w ciągu kilku minut. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem.
@@ -78,5 +79,7 @@ pl:
       not_found: nie znaleziono
       not_locked: było zablokowane
       not_saved:
-        one: '1 błąd uniemożliwił zapisanie zasobu %{resource}:'
-        other: 'Błędy (%{count}) uniemożliwiły zapisanie zasobu %{resource}:'
+        few: 'Błędy (%{count}) uniemożliwiły zapisanie tego %{resource}:'
+        many: 'Błędy (%{count}) uniemożliwiły zapisanie tego %{resource}:'
+        one: '1 błąd nie uniemożliwił zapisanie %{resource}:'
+        other: 'Błędy (%{count}) uniemożliwiły zapisanie tego %{resource}:'
diff --git a/config/locales/devise.pt-BR.yml b/config/locales/devise.pt-BR.yml
index 5f47bc901a8e18f7dfee3264e3185994591379de..ede0048925015711ccfaadb231ee158b85eadc1c 100644
--- a/config/locales/devise.pt-BR.yml
+++ b/config/locales/devise.pt-BR.yml
@@ -18,9 +18,10 @@ pt-BR:
     mailer:
       confirmation_instructions:
         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.
         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'
+        subject: 'Mastodon: Instruções de confirmação para %{instance}'
         title: Verifique o endereço de e-mail
       email_changed:
         explanation: 'O e-mail associado à sua conta será mudado para:'
diff --git a/config/locales/devise.ru.yml b/config/locales/devise.ru.yml
index f80f7ad0534b6ecc7a7cb86cfca54710fd347e7e..2186066c9dde3fb98f55669a188a698aae660e42 100644
--- a/config/locales/devise.ru.yml
+++ b/config/locales/devise.ru.yml
@@ -24,7 +24,7 @@ ru:
         title: Подтвердите e-mail адрес
       email_changed:
         explanation: 'E-mail адрес Вашей учётной записи будет изменён на:'
-        extra: Если Вы не меняли адрес e-mail, возможно кто-то получил доступ к Вашей учётной записи. Пожалуйста, срочно смените пароль или свяжитесь с администратором узла, если у Вас нет доступа к учётной записи
+        extra: Если Вы не меняли адрес e-mail, возможно кто-то получил доступ к Вашей учётной записи. Пожалуйста, срочно смените пароль или свяжитесь с администратором узла, если у Вас нет доступа к учётной записи.
         subject: 'Mastodon: Адрес e-mail изменён'
         title: Новый адрес e-mail
       password_change:
diff --git a/config/locales/devise.sk.yml b/config/locales/devise.sk.yml
index a32fbe03bdfd8adde1e694ae7586d49e076956d4..16cd9262e2d0c7f5c43444b15ec670f74b8f1d2a 100644
--- a/config/locales/devise.sk.yml
+++ b/config/locales/devise.sk.yml
@@ -18,6 +18,7 @@ sk:
     mailer:
       confirmation_instructions:
         action: Potvŕď 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}'
@@ -29,7 +30,7 @@ sk:
         title: Nová emailová adresa
       password_change:
         explanation: Heslo k tvojmu účtu bolo zmenené.
-        extra: Pokiaľ si nezmenil/a svoje heslo, je pravdepodobné že niekto iný získal prístup k tvojmu účtu. Naliehavo preto prosím zmeň svoje heslo, alebo kontaktuj administrátora tohto serveru pokiaľ si vymknutý/á zo svojho účtu.
+        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:
@@ -59,22 +60,22 @@ sk:
       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 potvrdzujúcim registráciu bola poslaná na váš email. Pre aktváciu účtu, kliknite na daný odkaz.
-      update_needs_confirmation: Účet bol úspešne zmenený ale ešte potrebujeme overiť vašu novú emailovú adresu. Pre overenie prosím kliknite na link v správe ktorú sme vám poslali na email.
-      updated: Váš účet bol úspešne aktualizovaný.
+      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.
+      updated: Tvoj účet bol úspešne aktualizovaný.
     sessions:
-      already_signed_out: Odhlásenie bolo úspešné.
-      signed_in: Prihlásenie úspešné.
-      signed_out: Odhlásenie úspešné.
+      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é.
     unlocks:
-      send_instructions: O niekoľko minút obdržíte email s inštrukciami ako nastaviť nové heslo.
-      send_paranoid_instructions: Ak váš účet existuje, o niekoľko minút obdržíte email s inštrukciami ako ho odomknúť.
-      unlocked: Váš účet bol úspešne odomknutý. Prosím prihláste sa.
+      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.
+      unlocked: Tvoj účet bol úspešne odomknutý. Pre pokračovanie sa prosím prihlás.
   errors:
     messages:
-      already_confirmed: bol už potvrdený, skúste sa prihlásiť
-      confirmation_period_expired: musí byť potvrdený do %{period}, prosím požiadajte o nový
-      expired: expiroval, prosím, vyžiadajte si nový
+      already_confirmed: bol už potvrdený, skús sa prihlásiť
+      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_saved:
diff --git a/config/locales/devise.sr.yml b/config/locales/devise.sr.yml
index 9d1359695cb10bf205bc6f229a2b5784a2af5188..475d1e2a54c842168cc768cada8dc53be1388de0 100644
--- a/config/locales/devise.sr.yml
+++ b/config/locales/devise.sr.yml
@@ -17,11 +17,33 @@ sr:
       unconfirmed: Пре наставка морате потврдити свој налог.
     mailer:
       confirmation_instructions:
+        action: Потврдите адресу е-поште
+        action_with_app: Потврди и врати се на %{app}
+        explanation: Направили сте налог на %{host} са адресом ове е-поште. На један клик сте удаљени од активирања. Ако ово нисте ви, молимо игноришите ову е-пошту.
+        extra_html: Молимо да такође проверите <a href="%{terms_path}"> правила ове инстанце и <a href="%{policy_path}"> наше услове коришћења.
         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:
diff --git a/config/locales/devise.tr.yml b/config/locales/devise.tr.yml
deleted file mode 100644
index fb819978f1fe54b6dc3c0c4ccda71ded4f13ea41..0000000000000000000000000000000000000000
--- a/config/locales/devise.tr.yml
+++ /dev/null
@@ -1,51 +0,0 @@
----
-tr:
-  simple_form:
-    hints:
-      defaults:
-        avatar: En fazla 2MB olacak şekilde PNG, GIF veya JPG formatında yükleyiniz. 400x400px büyüklüğüne indirgenecektir
-        display_name: "%{count} karakter kaldı"
-        header: En fazla 2MB olacak şekilde PNG, GIF veya JPG formatında yükleyiniz. 700x335px 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.
-        note: "%{count} karakter kaldı"
-      imports:
-        data: Diğer Mastodon sunucusundan dışarı aktardığınız CSV dosyası
-      sessions:
-        otp: Telefonunuzdaki two-factor kodunuzu giriniz veya kurtarma kodlarınızdan birini giriniz.
-    labels:
-      defaults:
-        avatar: Profil resmi
-        confirm_new_password: Yeni parolanız (tekrar)
-        confirm_password: Parolanız (tekrar)
-        current_password: Mevcut parolanız
-        data: Dosya
-        display_name: Görünen adınız
-        email: E-posta adresiniz
-        header: Kapak resmi
-        locale: Dil
-        locked: Hesabımı kilitle
-        new_password: Yeni parolanız
-        note: KiÅŸisel bilgiler
-        otp_attempt: İki-faktörlü kod
-        password: Parolanız
-        setting_auto_play_gif: GIF'leri otomatik oynatt
-        setting_boost_modal: Boost etmeden önce onay diyaloğu göster
-        setting_default_privacy: Gönderi gizliliği
-        severity: Zorluk
-        type: Dosya türü
-        username: Kullanıcı adınız
-      interactions:
-        must_be_follower: Takipçim olmayan kişilerden gelen bildirimleri engelle
-        must_be_following: Takip etmediÄŸim kiÅŸilerden gelen bildirimleri engelle
-      notification_emails:
-        digest: Özet e-postaları gönder
-        favourite: Biri durumumu favorilerine eklediginde bana e-posta gönder
-        follow: Biri beni takip ettiğinde bana e-posta gönder
-        follow_request: Biri bana takip isteği gönderdiğinde, bana e-posta gönder
-        mention: Biri benden bahsettiğinde, bana e-posta gönder
-        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/devise.uk.yml b/config/locales/devise.uk.yml
index 70ac6e4b29e7d57c60eaceb4dababeb276e2d73c..6ec01b3d7cdd97fbebbe2339ab9e257e17b97369 100644
--- a/config/locales/devise.uk.yml
+++ b/config/locales/devise.uk.yml
@@ -11,13 +11,13 @@ uk:
       invalid: Неправильний %{authentication_keys} або пароль.
       last_attempt: У вас є остання спроба, після якої вхід буде заблокований.
       locked: Ваш акаунт заблокований.
-      not_found_in_database: Неправильні %{authentication_keys} або пароль.
+      not_found_in_database: Неправильний %{authentication_keys} або пароль.
       timeout: Ваша сесія вичерпана. Будь ласка, зайдіть знову, щоб продовжити.
       unauthenticated: Для продовження Вам потрібно увійти або зареєструватися.
       unconfirmed: Для продовження Вам потрібно підтвердити Вашу поштову скриньку.
     mailer:
       confirmation_instructions:
-        subject: 'Mastodon: Інструкції для підтвердження'
+        subject: 'Mastodon: Інструкції для підтвердження %{instance}'
       password_change:
         subject: 'Mastodon: Ваш пароль змінений'
       reset_password_instructions:
diff --git a/config/locales/devise.zh-HK.yml b/config/locales/devise.zh-HK.yml
index 79e5a3d25dfe48a55a9ca9b94da193bc6517de7f..b7d88ef941abe06b2ce66068683cb020359d1eda 100644
--- a/config/locales/devise.zh-HK.yml
+++ b/config/locales/devise.zh-HK.yml
@@ -20,7 +20,7 @@ zh-HK:
         action: 驗證電子郵件地址
         explanation: 你在 %{host} 上使用這個電子郵件地址建立了一個帳戶。只需點擊下面的連結,即可啟用帳戶。如果你並沒有建立過帳戶,請忽略此郵件。
         extra_html: 請記得閱讀本服務站的<a href="%{terms_path}">相關規定</a>和<a href="%{policy_path}">使用條款</a>。
-        subject: 'Mastodon: 確認電郵地址'
+        subject: 'Mastodon: 確認電郵地址 %{instance}'
         title: 驗證電子郵件地址
       email_changed:
         explanation: 你的帳戶的電子郵件地址即將變更為:
diff --git a/config/locales/devise.zh-TW.yml b/config/locales/devise.zh-TW.yml
index 571429429281206fe49e817e30221c226dfde1d2..abbe45942301c78635457a6d3d7bb0456547309a 100644
--- a/config/locales/devise.zh-TW.yml
+++ b/config/locales/devise.zh-TW.yml
@@ -20,7 +20,7 @@ zh-TW:
         action: 驗證 E-mail 地址
         explanation: 您已經在 %{host} 上以此 E-mail 地址建立了一個帳號。您距離啟用它只剩一次點擊之遙了。如果這不是你,請忽略此 E-mail 。
         extra_html: 同時也請看看<a href="%{terms_path}">該站點的規則</a>與<a href="%{policy_path}">我們的服務條款</a>。
-        subject: 'Mastodon: 信箱驗證'
+        subject: 'Mastodon: 信箱驗證 %{instance}'
         title: 驗證 E-mail 地址
       email_changed:
         explanation: 您帳號的 E-mail 地址被變更為:
@@ -78,5 +78,5 @@ zh-TW:
       not_found: 找不到
       not_locked: 並未被鎖定
       not_saved:
-        one: 1 個錯誤使 %{resource} 無法被儲存︰
-        other: "%{count} 個錯誤使 %{resource} 無法被儲存︰"
+        one: 有 1 個錯誤讓此 %{resource} 無法儲存:
+        other: 有 %{count} 個錯誤讓此 %{resource} 無法儲存:
diff --git a/config/locales/doorkeeper.ast.yml b/config/locales/doorkeeper.ast.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ce88af797046e3690ae58b9c14d888805576183e
--- /dev/null
+++ b/config/locales/doorkeeper.ast.yml
@@ -0,0 +1,72 @@
+---
+ast:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: Nome de l'aplicación
+        website: Sitiu web de l'aplicación
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              invalid_uri: ha ser una URI válida.
+              relative_uri: ha ser una URI absoluta.
+  doorkeeper:
+    applications:
+      buttons:
+        cancel: Encaboxar
+        destroy: Destruyir
+        edit: Editar
+        submit: Unviar
+      index:
+        name: Nome
+      show:
+        actions: Aiciones
+        title: 'Aplicación: %{name}'
+    authorizations:
+      error:
+        title: Asocedió un fallu
+      new:
+        able_to: Va ser a
+        prompt: L'aplicación %{client_name} solicitó l'accesu a la to cuenta
+      show:
+        title: Copia esti códigu d'autorización y apégalu na aplicación.
+    authorized_applications:
+      buttons:
+        revoke: Revocar
+      index:
+        date_format: "%H:%M:%S %d-%m-%Y"
+        title: Les aplicaciones qu'autoricesti
+    errors:
+      messages:
+        invalid_token:
+          expired: Caducó'l pase d'accesu
+          revoked: Revocóse'l pase d'accesu
+          unknown: El pase d'accesu nun ye válidu
+        unauthorized_client: El veceru nun ta autorizáu pa facer esta solicitú usando esti métodu.
+        unsupported_response_type: El sirvidor d'autorización nun sofita esta triba de rempuesta.
+    layouts:
+      admin:
+        nav:
+          applications: Aplicaciones
+          oauth2_provider: Fornidor d'OAuth2
+    scopes:
+      read:accounts: ver información de cuentes
+      read:blocks: ver quién bloquies
+      read:filters: ver les tos peñeres
+      read:follows: ver quién sigues
+      read:lists: ver les tos llistes
+      read:mutes: ver quién silencies
+      read:notifications: ver los tos avisos
+      read:statuses: ver tolos estaos
+      write: modificar los datos de la to cuenta
+      write:accounts: modificar el to perfil
+      write:blocks: bloquiar cuentes y dominios
+      write:filters: crear peñeres
+      write:follows: siguir a xente
+      write:lists: crear llistes
+      write:media: xubir ficheros de medios
+      write:mutes: silenciar xente y conversaciones
+      write:notifications: llimpiar los tos avisos
+      write:statuses: espublizar estaos
diff --git a/config/locales/doorkeeper.co.yml b/config/locales/doorkeeper.co.yml
index 52777eaf0feef98bf25843926480449481600b23..542ad7c5747030f656a0b4b085144d9fd9a86c0c 100644
--- a/config/locales/doorkeeper.co.yml
+++ b/config/locales/doorkeeper.co.yml
@@ -114,7 +114,29 @@ co:
       application:
         title: Auturizazione OAuth riquestata
     scopes:
-      follow: bluccà, sbluccà, è reghje l’abbunamenti
-      push: Riceve nutificazione push per u vostru contu
-      read: leghje l’infurmazione di u vostru contu
-      write: mandà missaghji per voi
+      follow: Mudificà rilazione trà i conti
+      push: Riceve e vostre nutificazione push
+      read: leghje tutte l’infurmazioni di u vostru contu
+      read:accounts: Vede l'infurmazione di i conti
+      read:blocks: vede i vostri blucchimi
+      read:favourites: vede i vostri favuriti
+      read:filters: vede i vostri filtri
+      read:follows: vede i vostri abbunamenti
+      read:lists: vede e vostre liste
+      read:mutes: vede i vostri piattati
+      read:notifications: vede e vostre nutificazione
+      read:reports: vede i vostri signalamenti
+      read:search: ricercà per voi
+      read:statuses: vede tutti i statuti
+      write: mudificà i dati di u vostru contu
+      write:accounts: mudificà u prufile
+      write:blocks: bluccà conti è dumini
+      write:favourites: aghjustà statuti à i favuriti
+      write:filters: creà filtri
+      write:follows: siguità conti
+      write:lists: creà liste
+      write:media: caricà fugliali media
+      write:mutes: piattà persone è cunversazione
+      write:notifications: sguassà e nutificazione
+      write:reports: palisà altre persone
+      write:statuses: pubblicà statuti
diff --git a/config/locales/doorkeeper.cs.yml b/config/locales/doorkeeper.cs.yml
index 876f448c755c3f95d0d89e2e88b3eed9f62358e1..b9e9bc034930dc6a0e9a342e0e4527ad01f1407e 100644
--- a/config/locales/doorkeeper.cs.yml
+++ b/config/locales/doorkeeper.cs.yml
@@ -4,3 +4,139 @@ cs:
     attributes:
       doorkeeper/application:
         name: Název aplikace
+        redirect_uri: URI přesměrování
+        scopes: Rozsahy
+        website: Stránka aplikace
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              fragment_present: nesmí obsahovat fragment.
+              invalid_uri: musí být platné URI.
+              relative_uri: musí být apsolutní URI.
+              secured_uri: musí být URI HTTPS/SSL.
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: Autorizovat
+        cancel: Zrušit
+        destroy: Zničit
+        edit: Upravit
+        submit: Odeslat
+      confirmations:
+        destroy: Jste si jistý/á?
+      edit:
+        title: Upravit aplikaci
+      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
+        scopes: Oddělujte rozsahy mezerami. Pro použití výchozích rozsahů zanechte prázdné.
+      index:
+        application: Aplikace
+        callback_url: Zpáteční URL
+        delete: Smazat
+        name: Název
+        new: Nová aplikace
+        scopes: Rozsahy
+        show: Zobrazit
+        title: Vaše aplikace
+      new:
+        title: Nová aplikace
+      show:
+        actions: Akce
+        application_id: Klientský klíč
+        callback_urls: Zpáteční URL
+        scopes: Rozsahy
+        secret: Klientské tajemství
+        title: 'Aplikace: %{name}'
+    authorizations:
+      buttons:
+        authorize: Ověřit
+        deny: Zamítnout
+      error:
+        title: Vyskytla se chyba
+      new:
+        able_to: Bude moci
+        prompt: Aplikace %{client_name} vyžaduje přístup k vašemu účtu
+        title: Je vyžadována autorizace
+      show:
+        title: Zkopírujte tento autorizační kód a vložte ho do aplikace.
+    authorized_applications:
+      buttons:
+        revoke: Zamítnout
+      confirmations:
+        revoke: Jste si jistý/á?
+      index:
+        application: Aplikace
+        created_at: Autorizováno
+        date_format: "%d. %m. %Y %H:%M:%S"
+        scopes: Rozsahy
+        title: Vaše autorizované aplikace
+    errors:
+      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_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ý.
+        invalid_resource_owner: Poskytnuté přihlašovací údaje vlastníka zdroje nejsou platné, nebo vlastník zdroje nemůže být nalezen
+        invalid_scope: Požadovaný rozsah je neplatný, neznámý, nebo malformovaný.
+        invalid_token:
+          expired: Přístupový token vypršel
+          revoked: Přístupový token byl zamítnut
+          unknown: Přístupový token je neplatný
+        resource_owner_authenticator_not_configured: Nález Resource Owner selhal, protože Doorkeeper.configure.resource_owner_authenticator nebylo nakonfigurováno.
+        server_error: Autorizační server se setkal s neočekávanou chybou, která mu zabránila ve vykonání požadavku.
+        temporarily_unavailable: Autorizační server vás nyní nemůže obsloužit kvůli dočasnému přetížení či údržbě serveru.
+        unauthorized_client: Klient není autorizován k vykonání tohoto požadavku touto metodou.
+        unsupported_grant_type: Tento typ oprávnění není podporován autorizačním serverem.
+        unsupported_response_type: Autorizační server nepodporuje tento typ odpovědi.
+    flash:
+      applications:
+        create:
+          notice: Aplikace vytvořena.
+        destroy:
+          notice: Aplikace smazána.
+        update:
+          notice: Aplikace aktualizována.
+      authorized_applications:
+        destroy:
+          notice: Aplikace zamítnuta.
+    layouts:
+      admin:
+        nav:
+          applications: Aplikace
+          oauth2_provider: Poskytovatel OAuth2
+      application:
+        title: Je požadována autorizace OAuth
+    scopes:
+      follow: upravovat vztahy mezi profily
+      push: přijímat vaše push oznámení
+      read: vidět všechna data vašeho účtu
+      read:accounts: vidět informace o účtech
+      read:blocks: vidět vaše blokace
+      read:favourites: vidět vaše oblíbení
+      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: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
+      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: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:notifications: vymazávat vaše oznámení
+      write:reports: nahlašovat jiné uživatele
+      write:statuses: publikovat příspěvky
diff --git a/config/locales/doorkeeper.cy.yml b/config/locales/doorkeeper.cy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..87d7a86603123eb017426274c5293bd0b4502160
--- /dev/null
+++ b/config/locales/doorkeeper.cy.yml
@@ -0,0 +1,142 @@
+---
+cy:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: Enw rhaglen
+        redirect_uri: Ailgyfeirio URI
+        scopes: Rhinweddau
+        website: Gwefan cais
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              fragment_present: ni all gynnwys dernyn.
+              invalid_uri: rhaid iddo fod yn URI cyfredol.
+              relative_uri: rhaid iddo fod yn URI absoliwt.
+              secured_uri: rhaid iddo fod yn URI HTTPS/SSL.
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: Awdurdodi
+        cancel: Diddymu
+        destroy: Dinistrio
+        edit: Golygu
+        submit: Cyflwyno
+      confirmations:
+        destroy: Ydych chi'n sicr?
+      edit:
+        title: Golygwch y rhaglen
+      form:
+        error: Wps! Gwiriwch eich ffurflen am gamgymeriadau posib
+      help:
+        native_redirect_uri: Defnyddiwch %{native_redirect_uri} ar gyfer profion lleol
+        redirect_uri: Defnyddiwch un llinell i bob URI
+        scopes: Gwahanwch rinweddau gyda gofodau. Gadewch yn wag i ddefnyddio y rhinweddau rhagosodiedig.
+      index:
+        application: Rhaglen
+        callback_url: URL galw-nôl
+        delete: Dileu
+        name: Enw
+        new: Rhaglen newydd
+        scopes: Rhinweddau
+        show: Dangoswch
+        title: Eich rhaglenni
+      new:
+        title: Rhaglen newydd
+      show:
+        actions: Gweithredoedd
+        application_id: Allwedd cleient
+        callback_urls: URLau galw-nôl
+        scopes: Rhinweddau
+        secret: Cyfrinach Cleient
+        title: 'Rhaglen: %{name}'
+    authorizations:
+      buttons:
+        authorize: Awdurdodi
+        deny: Gwrthod
+      error:
+        title: Mae rhywbeth wedi mynd o'i le
+      new:
+        able_to: Mi fydd a'r gallu i
+        prompt: Mae'r ap %{client_name} yn gofyn caniatad i gal mynediad i'ch cyfrif
+        title: Angen awdurdodi
+      show:
+        title: Copiwch y côd awdurdodi a gludiwch i'r rhaglen.
+    authorized_applications:
+      buttons:
+        revoke: Diddymu
+      confirmations:
+        revoke: Ydych chi'n sicr?
+      index:
+        application: Rhaglen
+        created_at: Awdurdodedig
+        date_format: "%Y-%m-%d %H:%M:%S"
+        scopes: Rhinweddau
+        title: Eich rhaglenni awdurdodedig
+    errors:
+      messages:
+        access_denied: Mae perchennog yr adnodd neu'r gweinydd awdurdodi wedi atal y cais.
+        credential_flow_not_configured: Llif meini prawf cyfrinair perchennog yr adnodd wedi methu achos fod Doorkeeper.configure.resource_owner_from_credentials heb ei ffurfweddu.
+        invalid_client: Methwyd dilysu cleient oherwydd cleient anhysbys, methiant i gynnwys dilysu cleient, neu defnydd o ddull dilysu nid yw'n cael ei gefnodi.
+        invalid_grant: Mae'r grant dilysu a ddarparwyd yn annilys, wedi dod i ben, wedi'i wrthod, ddim yn cyfateb a'r URI ailgyferio a ddefnyddiwyd yn y cais dilysu, neu wedi ei ddarparu i gleient arall.
+        invalid_redirect_uri: Nid yw'r uri ailgyfeirio cynnwysiedig yn gyfredol.
+        invalid_request: Nid yw'r cais yn cynnwys paramedr angenrheidiol, yn cynnwys paramader paramedr nad yw'n cael ei gefnogi, neu wedi ei gamffurfio mewn rhyw fodd arall.
+        invalid_resource_owner: Nid yw meini prawf perchennog yr adnodd yn ddilys, neu ni ellir canfod perchennog yr adnodd
+        invalid_scope: Mae'r sgôp a geisiwyd amdano yn annilys, anhysbys, neu'n gamffurfiedig.
+        invalid_token:
+          expired: Daeth y tocyn mynediad i ben
+          revoked: Gwrthodwyd y tocyn mynediad
+          unknown: Mae'r tocyn mynediad yn annilys
+        resource_owner_authenticator_not_configured: Methwyd canfod Perchenog Adnodd achos fod Doorkeeper.configure.resource_owner_authenticator heb ei gydffurfio.
+        server_error: Daeth y gweinydd awdurdodi ar draws gyflwr annisgwyl wnaeth ei atal rhag cyflawni'r cais.
+        temporarily_unavailable: Nid yw'r gweinydd awdurdodi yn gallu gweithredu y cais hwn ar hyn o bryd oherwydd gorlwytho dros dro neu gwaith cynnal a chadw ar y gweinydd hwn.
+        unauthorized_client: Nid yw'r cleient wedi ei awdurdodi i berfformio'r cais hwn yn defnyddio'r dull hwn.
+        unsupported_grant_type: Nid yw'r math o ganiatad awdurdodi yma'n cael ei gefnogi gan y gweinydd awdurdodi.
+        unsupported_response_type: Nid yw'r gweinydd awdurdodi yn cefnogi y math yma o ymateb.
+    flash:
+      applications:
+        create:
+          notice: Crewyd y rhaglen.
+        destroy:
+          notice: Dilëwyd y rhaglen.
+        update:
+          notice: Diweddarwyd y rhaglen.
+      authorized_applications:
+        destroy:
+          notice: Diddymwyd y cais.
+    layouts:
+      admin:
+        nav:
+          applications: Rhaglenni
+          oauth2_provider: Darparwr OAuth2
+      application:
+        title: Mae awdurdodiad OAuth yn ofynnol
+    scopes:
+      follow: addasu perthnasau cyfrif
+      push: derbyn eich hysbysiadau PUSH
+      read: darllen holl ddata eich cyfrif
+      read:accounts: gweld gwybodaeth y cyfrif
+      read:blocks: gweld eich blociau
+      read:favourites: gweld eich ffefrynnau
+      read:filters: gweld eich hidlwyr
+      read:follows: gweld eich dilynwyr
+      read:lists: gweld eich rhestrau
+      read:mutes: gweld y rheini wedi'i tewi
+      read:notifications: gweld eich hysbysiadau
+      read:reports: gweld eich adroddiadau
+      read:search: edrych ar eich rhan
+      read:statuses: gweld pob statws
+      write: addasu holl ddata eich cyfri
+      write:accounts: addasu eich proffil
+      write:blocks: blocio cyfrifon a parthau
+      write:favourites: hoff dŵtiau
+      write:filters: creu hidlwyr
+      write:follows: dilyn pobl
+      write:lists: creu rhestrau
+      write:media: uwchlwytho ffeiliau cyfryngau
+      write:mutes: tawelu pobl a sgyrsiau
+      write:notifications: clirio eich hysbysiadau
+      write:reports: adrodd pobl eraill
+      write:statuses: cyhoeddi tŵt
diff --git a/config/locales/doorkeeper.da.yml b/config/locales/doorkeeper.da.yml
index 051bfd237bcf111d8de87156c114f965b9aa95d2..df964e4b1f8228214dd5d2dba31be82a18e77b72 100644
--- a/config/locales/doorkeeper.da.yml
+++ b/config/locales/doorkeeper.da.yml
@@ -78,14 +78,22 @@ da:
     errors:
       messages:
         access_denied: Ejeren af ressourcen eller godkendelses serveren afviste anmodningen.
+        credential_flow_not_configured: Flytning af ressourceejers adgangskode mislykkedes grundet Doorkeeper.configure.resource_owner_from_credentials ikke er opsat.
+        invalid_client: Klient autentikationen mislykkedes grundet en ukendt klient, ingen klient autentikation fulgte med, eller en ikke-understøttet metode.
+        invalid_grant: Autoriseringen er ugyldig, udløbet, ophævet, passer ikke med den henvisnings URI der blev brugt i autoriserings anmodningen, eller blev givet til en anden klient.
         invalid_redirect_uri: Ormdirigerings-uri'en der blev angivet er ikke gyldig.
         invalid_request: Anmodningen mangler en parametre, inkluderer en ikke understøttet parametre værdi eller er på en eller anden måde deformeret.
+        invalid_resource_owner: De angivne ressource ejer kredentialer er ikke gyldige, eller ressource ejeren kunne ikke blive fundet
         invalid_scope: Det anmodede omfang er ugyldigt, ukendt eller deformeret.
         invalid_token:
           expired: Adgangs-beviset er udløbet
           revoked: Adgangs-beviset er blevet ophævet
           unknown: Adgangs-beviset er ugyldigt
+        resource_owner_authenticator_not_configured: Ressource ejeren kunne ikke blive fundet grundet Doorkeeper.configure.resource_owner_authenticator ikke er konfigureret.
+        server_error: Autoriserings serveren blev mødt med en uventet betingelse der forhindrede den i at færdiggøre anmodningen.
+        temporarily_unavailable: Autoriserings serveren er på nuværende tidspunkt ikke i stand til at håndtere anmodningen grundet midlertidig overlast eller serveren er ved at blive opdateret.
         unauthorized_client: Klienten er ikke godkendt til at udføre denne anmodning ved at bruge denne metode.
+        unsupported_grant_type: Autoriserings typen understøttes ikke af autoriserings serveren.
         unsupported_response_type: Godkendelses serveren understøtter ikke denne type respons.
     flash:
       applications:
diff --git a/config/locales/doorkeeper.de.yml b/config/locales/doorkeeper.de.yml
index 7f37641803b1fa2307b116bb3345903d43c57e1c..bf4b06e7c25909751fa8abe909fe40df12e9fd7f 100644
--- a/config/locales/doorkeeper.de.yml
+++ b/config/locales/doorkeeper.de.yml
@@ -15,7 +15,7 @@ de:
               fragment_present: darf kein Fragment enthalten.
               invalid_uri: muss ein valider URI sein.
               relative_uri: muss ein absoluter URI sein.
-              secured_uri: muss ein HTTPS/SSL-URI sein.
+              secured_uri: muss ein HTTPS-/SSL-URI sein.
   doorkeeper:
     applications:
       buttons:
@@ -59,7 +59,7 @@ de:
       error:
         title: Ein Fehler ist aufgetreten
       new:
-        able_to: Es wird in der Lage sein zu
+        able_to: 'Es wird folgende Befugnisse haben:'
         prompt: Die Anwendung %{client_name} verlangt Zugriff auf dein Konto
         title: Autorisierung erforderlich
       show:
@@ -115,13 +115,13 @@ de:
         title: OAuth-Autorisierung nötig
     scopes:
       follow: Kontenbeziehungen verändern
-      push: erhalte deine Push-Benachrichtigungen
+      push: deine Push-Benachrichtigungen erhalten
       read: all deine Daten lesen
       read:accounts: deine Konteninformationen einsehen
       read:blocks: deine Blockaden einsehen
       read:favourites: deine Favoriten ansehen
       read:filters: deine Filter ansehen
-      read:follows: deine Follows sehen
+      read:follows: sehen, wem du folgst
       read:lists: deine Listen sehen
       read:mutes: deine Stummschaltungen einsehen
       read:notifications: deine Benachrichtigungen sehen
diff --git a/config/locales/doorkeeper.eo.yml b/config/locales/doorkeeper.eo.yml
index 9713c462c4ba1c1a9245359c1320eef51607a2c1..e80ba3236ae361737a0747bdd09cc9a7990ae76e 100644
--- a/config/locales/doorkeeper.eo.yml
+++ b/config/locales/doorkeeper.eo.yml
@@ -114,7 +114,29 @@ eo:
       application:
         title: OAuth-a rajtigo bezonata
     scopes:
-      follow: sekvi, bloki, malbloki kaj malsekvi kontojn
-      push: ricevi puŝ-sciigojn por via konto
-      read: legi la datumojn de via konto
-      write: mesaĝi kiel vi
+      follow: ŝanĝi rilatojn al aliaj kontoj
+      push: ricevi viajn puŝ-sciigojn
+      read: legi ĉiujn datumojn de via konto
+      read:accounts: vidi la informojn de la konto
+      read:blocks: vidi viajn blokojn
+      read:favourites: vidi viajn stelumojn
+      read:filters: vidi viajn filtrilojn
+      read:follows: vidi viajn sekvatojn
+      read:lists: vidi viajn listojn
+      read:mutes: vidi viajn silentigojn
+      read:notifications: vidi viajn sciigojn
+      read:reports: vidi viajn signalojn
+      read:search: serĉi vianome
+      read:statuses: vidi ĉiujn mesaĝojn
+      write: ŝanĝi ĉiujn datumojn de via konto
+      write:accounts: ŝanĝi vian profilon
+      write:blocks: bloki kontojn kaj domajnojn
+      write:favourites: stelumitaj mesaĝoj
+      write:filters: krei filtrilojn
+      write:follows: sekvi homojn
+      write:lists: krei listojn
+      write:media: alŝuti aŭdovidaĵojn
+      write:mutes: silentigi homojn kaj konversaciojn
+      write:notifications: forigi viajn sciigojn
+      write:reports: signali aliajn homojn
+      write:statuses: publikigi mesaĝojn
diff --git a/config/locales/doorkeeper.eu.yml b/config/locales/doorkeeper.eu.yml
index aba3166ac565bac335b6874a0e805575dc544af3..f98babae657e3d4160e2c6c65f193e5dcb4c3ee0 100644
--- a/config/locales/doorkeeper.eu.yml
+++ b/config/locales/doorkeeper.eu.yml
@@ -114,7 +114,29 @@ eu:
       application:
         title: OAuth autorizazioa behar da
     scopes:
-      follow: jarraitu kontuak, blokeatu, utzi jarraitzeari eta desblokeatu
-      push: jaso zure kontuaren push jakinarazpenak
-      read: irakurri zure kontuko datuak
-      write: zure izenean argitaratu
+      follow: aldatu kontuaren erlazioak
+      push: jaso push jakinarazpenak
+      read: irakurri zure kontuko datu guztiak
+      read:accounts: ikusi kontuaren informazioa
+      read:blocks: ikusi zure blokeoak
+      read:favourites: ikusi zure gogokoak
+      read:filters: ikusi zure iragazkiak
+      read:follows: ikusi zuk jarraitutakoak
+      read:lists: ikusi zure zerrendak
+      read:mutes: ikusi zuk mutututakoak
+      read:notifications: ikusi zure jakinarazpenak
+      read:reports: ikusi zure salaketak
+      read:search: bilatu zure izenean
+      read:statuses: ikusi mezu guztiak
+      write: kontuaren datu guztiak aldatzea
+      write:accounts: zure profila aldatzea
+      write:blocks: kontuak eta domeinuak blokeatzea
+      write:favourites: gogoko mezuak
+      write:filters: sortu iragazkiak
+      write:follows: jarraitu jendea
+      write:lists: sortu zerrendak
+      write:media: igo multimedia fitxategiak
+      write:mutes: mututu pertsonak eta elkarrizketak
+      write:notifications: garbitu zure jakinarazpenak
+      write:reports: salatu beste jendea
+      write:statuses: argitaratu mezuak
diff --git a/config/locales/doorkeeper.fr.yml b/config/locales/doorkeeper.fr.yml
index 09660cb49c4305285e0530eb8147fae2a1e828fd..eae691659f5edc62b54b3233822dda663e70c8e8 100644
--- a/config/locales/doorkeeper.fr.yml
+++ b/config/locales/doorkeeper.fr.yml
@@ -7,7 +7,7 @@ fr:
         redirect_uri: L’URL de redirection
         scope: Portée
         scopes: Étendues
-        website: Site web de l'application
+        website: Site web de l’application
     errors:
       models:
         doorkeeper/application:
@@ -64,7 +64,7 @@ fr:
         prompt: Autoriser %{client_name} à utiliser votre compte ?
         title: Autorisation requise
       show:
-        title: Copiez ce code d'autorisation et collez-le dans l'application.
+        title: Copiez ce code d’autorisation et collez-le dans l’application.
     authorized_applications:
       buttons:
         revoke: Annuler
@@ -119,11 +119,12 @@ fr:
       push: recevoir vos notifications
       read: lire toutes les données de votre compte
       read:accounts: voir les informations du compte
-      read:blocks: voir vos bloqués
+      read:blocks: voir vos bloquages
       read:favourites: voir vos favoris
       read:filters: voir vos filtres
+      read:follows: voir vos suivis
       read:lists: voir vos listes
-      read:mutes: voir vos silenciés
+      read:mutes: voir vos masquages
       read:notifications: voir vos notifications
       read:reports: voir vos rapports
       read:search: rechercher en votre nom
@@ -131,10 +132,12 @@ fr:
       write: modifier toutes les données de votre compte
       write:accounts: modifier votre profil
       write:blocks: bloquer des comptes et des domaines
+      write:favourites: statuts favoris
       write:filters: créer des filtres
       write:follows: suivre les gens
       write:lists: créer des listes
       write:media: téléverser des fichiers-média
-      write:mutes: silencier des gens et des conversations
+      write:mutes: masquer des gens et des conversations
       write:notifications: nettoyer vos notifications
+      write:reports: rapporter d’autres personnes
       write:statuses: publier des statuts
diff --git a/config/locales/doorkeeper.it.yml b/config/locales/doorkeeper.it.yml
index 37b6f101333fe31630dc4ebf7d77c87a8763c76b..a76130bb94e384b5a0070b7575a3bdddd46d1049 100644
--- a/config/locales/doorkeeper.it.yml
+++ b/config/locales/doorkeeper.it.yml
@@ -138,4 +138,5 @@ it:
       write:media: caricare media
       write:mutes: silenziare persone e conversazioni
       write:notifications: cancellare le tue notifiche
+      write:reports: fare rapporto su altre persone
       write:statuses: pubblicare status
diff --git a/config/locales/doorkeeper.ja.yml b/config/locales/doorkeeper.ja.yml
index 76174ef797869bbd1c46cb734abf32c61f1d97e1..9bc2d9a80fcf27f6e41b046b61bac4289c10ed91 100644
--- a/config/locales/doorkeeper.ja.yml
+++ b/config/locales/doorkeeper.ja.yml
@@ -133,7 +133,7 @@ ja:
       write:blocks: ユーザーのブロックやドメインの非表示
       write:favourites: トゥートのお気に入り登録
       write:filters: フィルターの変更
-      write:follows: フォローの変更
+      write:follows: あなたの代わりにフォロー、アンフォロー
       write:lists: リストの変更
       write:media: メディアのアップロード
       write:mutes: アカウントや会話のミュート
diff --git a/config/locales/doorkeeper.ka.yml b/config/locales/doorkeeper.ka.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e462e66f1585657bdd7486935809d8ebca166a42
--- /dev/null
+++ b/config/locales/doorkeeper.ka.yml
@@ -0,0 +1,142 @@
+---
+ka:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: აპლიკაციის სახელი
+        redirect_uri: გადამისამართების ური
+        scopes: ფარგლები
+        website: აპლიკაციის ვებ-საიტი
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              fragment_present: ვერ ექნება ფრაგმეტი.
+              invalid_uri: უნდა იყოს ვალიდური ური.
+              relative_uri: უნდა იყოს აბსოლუტური ური.
+              secured_uri: უნდა იყოს ჰტტპს/სსლ ური.
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: ავტორიზაცია
+        cancel: უარყოფა
+        destroy: გაუქმება
+        edit: შეცვლა
+        submit: გაგრძელება
+      confirmations:
+        destroy: დარწმუნებული ხართ?
+      edit:
+        title: აპლიკაციის შეცვლა
+      form:
+        error: უპს! შესაძლო შეცდომებზე შეამოწმეთ თქვენი ფორმა
+      help:
+        native_redirect_uri: ლოკალური ტესტებისთვის მოიხმარეთ %{native_redirect_uri}
+        redirect_uri: გამოიყენეთ ერთი ხაზი თითო ური-სთვის
+        scopes: ფარგლები გამოჰყავით სიცარიელით. საწყისი ფარგლის გამოსაყენებლად დატოვეთ ცარიელი.
+      index:
+        application: აპლიკაცია
+        callback_url: ქოლბექ ურლ
+        delete: გაუქმება
+        name: სახელი
+        new: ახალი აპლიკაცია
+        scopes: ფარგლები
+        show: ჩვენება
+        title: თქვენი აპლიკაციები
+      new:
+        title: ახალი აპლიკაცია
+      show:
+        actions: მოქმედებები
+        application_id: კლიენტის გასაღები
+        callback_urls: ქოლბექ ურლები
+        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: რესურსის მფლობელმა ან აუტორიზაციის სერვერმა აკრძალა ეს მოთხოვნა.
+        credential_flow_not_configured: რესურის მფლობელის პაროლის რწმუნებულებების ნაკადი ვერ შესრულდა არაკონფიგურირებული Doorkeeper.configure.resource_owner_from_credentials გამო.
+        invalid_client: ამოუცნობი კლიენტის გამო კლიენტ აუტენტიფიკაცია ვერ მოხერხდა, კლიენტის აუტენტიფიკაცია არ იყო თან დართული, ან მხარდაუჭერელი აუტენტიფიკაციის მეთოდი.
+        invalid_grant: მოწოდებული ავტორიზაციის გრანტი არასწორია, ვადაგასულია, გაუქმებულია არ ემთხვევა გადამისამართების ურის, რომელიც მოიხმარება ავტორიზაცის მოთხოვნაში, ან მიეცა სხვა კლიენტს.
+        invalid_redirect_uri: მითითებული გადამისამართების ური არაა ვალიდური.
+        invalid_request: მოთხოვნას აკლია აუცილებელი პარამეტრი, მოიცავს მხარდაუჭერელ პარამეტრის მნიშვნელობას, ან სხვაგვარად არაა გამართული.
+        invalid_resource_owner: მოწოდებული რესურსის მფლობელის რწმუნებულებები არაა ვალიდური, ან მფლობელის პონვა ვერ ხერხდება
+        invalid_scope: მოთხოვნილი ფარგალი არასწორია, ამოუცნობია ან არაა გამართული.
+        invalid_token:
+          expired: წვდომის ტოკენს გაუვიდა ვადა
+          revoked: წვდომის ტოკენი გაუქმდა
+          unknown: წვდომის ტოკენი არაა ვალიდური
+        resource_owner_authenticator_not_configured: რესურსის მფლობელის მოპოვება არ შედგა Doorkeeper.configure.resource_owner_authenticator კონფიგურაციის არ არსებობის გამო.
+        server_error: აუტორიზაციის სერვერს შეხვდა მოულოდნელი მდგომარეობა, რამაც ხელი შეუშალა მას აღესრულებინა მოთხონვა.
+        temporarily_unavailable: ავტორიზაციის სერვერი ამჟამად ვერ ახერხებს მოთხოვნის შემუშავებას დროებითი გადატვირთვის ან სერვერის შენარჩუნების გამო.
+        unauthorized_client: კლიენტი არაა ავტორიზებული შეასრულოს ეს მოთხოვნა ამ მეთოდით.
+        unsupported_grant_type: ავტორიზაციის გრანტის სახეობა არაა მხარდაჭერილი ავტორიზაციის სერვერის მიერ.
+        unsupported_response_type: ავტორიზაციის სერვერი არ უჭერს მხარს ამ პასუხის სახეობას.
+    flash:
+      applications:
+        create:
+          notice: აპლიკაცია შეიქმნა.
+        destroy:
+          notice: აპლიკაცია გაუქმდა.
+        update:
+          notice: აპლიკაცია განახლდა.
+      authorized_applications:
+        destroy:
+          notice: აპლიკაცია წაიშალა.
+    layouts:
+      admin:
+        nav:
+          applications: აპლიკაციები
+          oauth2_provider: ოუ-აუთ2 პროვაიდერი
+      application:
+        title: საჭიროა ოუ-აუთ ავტორიზაცია
+    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.pl.yml b/config/locales/doorkeeper.pl.yml
index 2e0254864c42b98c18f443ce485f47c43b1dd6da..de724f6c97bfa9f9c8c62e318a0727ec88ef46c9 100644
--- a/config/locales/doorkeeper.pl.yml
+++ b/config/locales/doorkeeper.pl.yml
@@ -90,7 +90,7 @@ pl:
           revoked: Token dostępowy został unieważniony
           unknown: Token dostępowy jest błędny
         resource_owner_authenticator_not_configured: Wyszukiwanie właściciela zasobu nie powiodło się, ponieważ Doorkeeper.configure.resource_owner_authenticator nie został skonfigurowany.
-        server_error: Serwer uwierzytelniający napotkał nieoczekiwand warunki, które uniemożliwiły obsłużenie żądania.
+        server_error: Serwer uwierzytelniający napotkał nieoczekiwane warunki, które uniemożliwiły obsłużenie żądania.
         temporarily_unavailable: Serwer uwierzytelniający nie jest obecnie w stanie obsłużyć żądania z powodu tymczasowego przeciążenia lub prac konserwacyjnych.
         unauthorized_client: Klient nie jest uprawniony do wykonania tego żądania przy pomocy tej metody.
         unsupported_grant_type: Ten typ grantu uwierzytelniajÄ…cego nie jest wspierany przez serwer uwierzytelniajÄ…cy.
diff --git a/config/locales/doorkeeper.pt-BR.yml b/config/locales/doorkeeper.pt-BR.yml
index afacfd7f7f02927c6b4b582637f3d711de02dc2e..dfab853c64cee908143b17064cb7acb9b3ae4b08 100644
--- a/config/locales/doorkeeper.pt-BR.yml
+++ b/config/locales/doorkeeper.pt-BR.yml
@@ -114,7 +114,29 @@ pt-BR:
       application:
         title: Autorização OAuth obrigatória
     scopes:
-      follow: seguir, bloquear, desbloquear e deixar de seguir outras contas
-      push: receber notificações push na sua conta
-      read: ler os dados da sua conta
-      write: postar em seu nome
+      follow: modificar as relações com outras contas
+      push: receber suas notificações push
+      read: ler todos os dados da sua conta
+      read:accounts: ver as informações da conta
+      read:blocks: ver seus bloqueios
+      read:favourites: ver seus favoritos
+      read:filters: ver seus filtros
+      read:follows: ver quem você segue
+      read:lists: ver suas listas
+      read:mutes: ver seus usuários silenciados
+      read:notifications: ver suas notificações
+      read:reports: ver suas denúncias
+      read:search: buscar em seu nome
+      read:statuses: ver todos os status
+      write: modificar todos os dados da sua conta
+      write:accounts: modificar seu perfil
+      write:blocks: bloquear contas e domínios
+      write:favourites: status favoritos
+      write:filters: criar filtros
+      write:follows: seguir pessoas
+      write:lists: criar listas
+      write:media: enviar arquivos de mídia
+      write:mutes: silenciar pessoas e conversas
+      write:notifications: limpar suas notificações
+      write:reports: reportar outras pessoas
+      write:statuses: publicar status
diff --git a/config/locales/doorkeeper.ro.yml b/config/locales/doorkeeper.ro.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fea4baf60dee067ea84fcf9b88fa857a86a862db
--- /dev/null
+++ b/config/locales/doorkeeper.ro.yml
@@ -0,0 +1,3 @@
+---
+ro:
+  doorkeeper: {}
diff --git a/config/locales/doorkeeper.ru.yml b/config/locales/doorkeeper.ru.yml
index 0a88d628e5413644ed2f2855c767f0b6139a2736..f3731755959e60f738d82ba09c461af969aa2f38 100644
--- a/config/locales/doorkeeper.ru.yml
+++ b/config/locales/doorkeeper.ru.yml
@@ -72,7 +72,7 @@ ru:
       index:
         application: Приложение
         created_at: Авторизовано
-        date_format: "%Y-%m-%d %H:%M:%S"
+        date_format: "%d.%m.%Y %H:%M:%S"
         scopes: Разрешения
         title: Ваши авторизованные приложения
     errors:
@@ -117,4 +117,26 @@ ru:
       follow: подписываться, отписываться, блокировать и разблокировать аккаунты
       push: принимать 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.sl.yml b/config/locales/doorkeeper.sl.yml
index 0967ef424bce6791893e9a57bb952f80fd536e93..c2745708942ac78a6796c4487181d3d938aa2d29 100644
--- a/config/locales/doorkeeper.sl.yml
+++ b/config/locales/doorkeeper.sl.yml
@@ -1 +1,6 @@
-{}
+---
+sl:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: Ime programa
diff --git a/config/locales/doorkeeper.uk.yml b/config/locales/doorkeeper.uk.yml
index d80abf01a67cef75b71279d6b7ee7ab72826383e..205ad026f1e69255ff069f0ad9d086efc47182b4 100644
--- a/config/locales/doorkeeper.uk.yml
+++ b/config/locales/doorkeeper.uk.yml
@@ -5,6 +5,8 @@ uk:
       doorkeeper/application:
         name: Ім'я
         redirect_uri: URI перенаправлення
+        scopes: Рамки
+        website: Веб-сайт додатку
     errors:
       models:
         doorkeeper/application:
diff --git a/config/locales/el.yml b/config/locales/el.yml
index 9c4f0c2a26b77559da828a3ab16902489c165158..5930ef3e9ba21f8a5a0a902e78a8f5a53b29d944 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -4,14 +4,14 @@ el:
     about_hashtag_html: Αυτά είναι κάποια από τα δημόσια τουτ σημειωμένα με <strong>#%{hashtag}</strong>. Μπορείς να αλληλεπιδράσεις με αυτά αν έχεις λογαριασμό οπουδήποτε στο fediverse.
     about_mastodon_html: Το Mastodon είναι ένα κοινωνικό δίκτυο που βασίζεται σε ανοιχτά δικτυακά πρωτόκολλα και ελεύθερο λογισμικό ανοιχτού κώδικα. Είναι αποκεντρωμένο όπως το e-mail.
     about_this: Σχετικά
-    administered_by: 'Διαχειρίζεται από:'
+    administered_by: 'Διαχειριστής:'
+    api: API
+    apps: Εφαρμογές κινητών
     closed_registrations: Αυτή τη στιγμή οι εγγραφές σε αυτό τον κόμβο είναι κλειστές. Αλλά! Μπορείς να βρεις έναν άλλο κόμβο για να ανοίξεις λογαριασμό και να έχεις πρόσβαση από εκεί στο ίδιο ακριβώς δίκτυο.
     contact: Επικοινωνία
     contact_missing: Δεν έχει οριστεί
     contact_unavailable: Μ/Δ
-    description_headline: Τι είναι το %{domain};
-    domain_count_after: άλλους διακομιστές
-    domain_count_before: Συνδέεται με
+    documentation: Τεκμηρίωση
     extended_description_html: |
       <h3>Ένα καλό σημείο για κανόνες</h3>
       <p>Η αναλυτική περιγραφή δεν έχει ακόμα οριστεί</p>
@@ -19,7 +19,7 @@ el:
       humane_approach_body: Μαθαίνοντας από τις αποτυχίες άλλων δικτύων, το Mastodon στοχεύει να κάνει σχεδιαστικά ηθικές επιλογές για να καταπολεμήσει την κακόβουλη χρήση των κοινωνικών δικτύων.
       humane_approach_title: Μια πιο ανθρώπινη προσέγγιση
       not_a_product_body: Το Mastodon δεν είναι ένα εμπορικό δίκτυο. Δεν έχει διαφημίσεις, δεν έχει εξόρυξη δεδομένων, δεν έχει περιφραγμένους κήπους. Δεν υπάρχει κεντρικό σημείο ελέγχου.
-      not_a_product_title: Είσαι ένας άνθρωπος, όχι κάποιο προϊόν
+      not_a_product_title: Είσαι άνθρωπος, όχι προϊόν
       real_conversation_body: Με 65,535 χαρακτήρες στη διάθεσή σου και υποστήριξη για λεπτομερή έλεγχο και προειδοποιήσεις πολυμέσων, μπορείς να εκφραστείς με τον τρόπο που θέλεις.
       real_conversation_title: Φτιαγμένο για αληθινή συζήτηση
       within_reach_body: Οι πολλαπλές εφαρμογές για το iOS, το Android και τις υπόλοιπες πλατφόρμες, χάρη σε ένα φιλικό προς τους προγραμματιστές οικοσύστημα API, σου επιτρέπουν να κρατάς επαφή με τους φίλους και τις φίλες σου οπουδήποτε.
@@ -28,25 +28,41 @@ el:
     hosted_on: Το Mastodon φιλοξενείται στο %{domain}
     learn_more: Μάθε περισσότερα
     other_instances: Λίστα κόμβων
+    privacy_policy: Πολιτική απορρήτου
     source_code: Πηγαίος κώδικας
-    status_count_after: καταστάσεις
-    status_count_before: Που έχουν γράψει
-    user_count_after: χρήστες
+    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: Ακόλουθοι
+    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}
-    posts: Τουτ
+    pin_errors:
+      following: Πρέπει ήδη να ακολουθείς το άτομο που θέλεις να επιδοκιμάσεις
+    posts:
+      one: Τουτ
+      other: Τουτ
+    posts_tab_heading: Τουτ
     posts_with_replies: Τουτ και απαντήσεις
-    remote_follow: Απομακρυσμένη παρακολούθηση
     reserved_username: Το όνομα χρήστη είναι κατειλημμένο
     roles:
       admin: Διαχειριστής
@@ -54,6 +70,9 @@ el:
       moderator: Μεσολαβητής
     unfollow: Διακοπή παρακολούθησης
   admin:
+    account_actions:
+      action: Εκτέλεση ενέργειας
+      title: Εκτέλεση ενέργειας διαχείρισης στο %{acct}
     account_moderation_notes:
       create: Άφησε σημείωση
       created_msg: Επιτυχής δημιουργία σημειώματος μεσολάβησης!
@@ -73,6 +92,7 @@ el:
       confirm: Επιβεβαίωση
       confirmed: Επιβεβαιώθηκε
       confirming: Προς επιβεβαίωση
+      deleted: Διαγραμμένοι
       demote: Υποβίβαση
       disable: Απενεργοποίηση
       disable_two_factor_authentication: Απενεργοποίηση 2FA
@@ -88,8 +108,11 @@ el:
       followers: Ακόλουθοι
       followers_url: URL ακολούθων
       follows: Ακολουθεί
+      header: Επικεφαλίδα
       inbox_url: URL εισερχομένων
+      invited_by: Προσκλήθηκε από
       ip: IP
+      joined: Γράφτηκε
       location:
         all: Όλες
         local: Τοπικά
@@ -99,6 +122,7 @@ el:
       media_attachments: Συνημμένα πολυμέσα
       memorialize: Μετατροπή σε νεκρολογία
       moderation:
+        active: Ενεργός/ή
         all: Όλα
         silenced: Αποσιωπημένα
         suspended: Σε αναστολή
@@ -106,13 +130,10 @@ el:
       moderation_notes: Σημειώσεις μεσολάβησης
       most_recent_activity: Πιο πρόσφατη δραστηριότητα
       most_recent_ip: Πιο πρόσφατη IP
+      no_limits_imposed: Χωρίς όρια
       not_subscribed: Άνευ συνδρομής
-      order:
-        alphabetic: Αλφαβητικά
-        most_recent: Πιο πρόσφατα
-        title: Ταξινόμηση
       outbox_url: URL εξερχομένων
-      perform_full_suspension: Κάνε πλήρη αναστολή
+      perform_full_suspension: Αναστολή
       profile_url: URL προφίλ
       promote: Προβίβασε
       protocol: Πρωτόκολλο
@@ -120,6 +141,7 @@ el:
       push_subscription_expires: Η εγγραφή PuSH λήγει
       redownload: Ανανέωση αβατάρ
       remove_avatar: Απομακρυσμένο αβατάρ
+      remove_header: Αφαίρεση επικεφαλίδας
       resend_confirmation:
         already_confirmed: Ήδη επιβεβαιωμένος χρήστης
         send: Επανάληψη αποστολής email επιβεβαίωσης
@@ -138,27 +160,31 @@ el:
       shared_inbox_url: URL κοινόχρηστων εισερχομένων
       show:
         created_reports: Αναφορές από αυτόν το λογαριασμό
-        report: καταγγελία
         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} άλλαξε τη διεύθυνση email του χρήστη %{target}
         confirm_user: Ο/Η %{name} επιβεβαίωσε τη διεύθυνση email του χρήστη %{target}
+        create_account_warning: Ο/Η %{name} έστειλε προειδοποίηση προς %{target}
         create_custom_emoji: Ο/Η %{name} ανέβασε νέο emoji %{target}
         create_domain_block: Ο/Η %{name} μπλόκαρε τον τομέα %{target}
         create_email_domain_block: Ο/Η %{name} έβαλε τον τομέα email %{target} σε μαύρη λίστα
         demote_user: Ο/Η %{name} υποβίβασε το χρήστη %{target}
+        destroy_custom_emoji: Ο/Η %{name} κατέστρεψε το emoji %{target}
         destroy_domain_block: Ο/Η %{name} ξεμπλόκαρε τον τομέα %{target}
         destroy_email_domain_block: Ο/Η %{name} έβαλε τον τομέα email %{target} σε λευκή λίστα
         destroy_status: Ο/Η %{name} αφαίρεσε την κατάσταση του/της %{target}
@@ -180,6 +206,7 @@ el:
         unsuspend_account: Ο/Η %{name} ήρε την παύση του λογαριασμού του χρήστη %{target}
         update_custom_emoji: Ο/Η %{name} ενημέρωσε το emoji %{target}
         update_status: Ο/Η %{name} ενημέρωσε την κατάσταση του/της %{target}
+      deleted_status: "(διαγραμμένη δημοσίευση)"
       title: Αρχείο ελέγχου
     custom_emojis:
       by_domain: Τομέας
@@ -204,8 +231,30 @@ el:
       title: Προσαρμοσμένα emoji
       unlisted: Μη καταχωρημένα
       update_failed_msg: Αδυναμία ενημέρωσης του emoji
-      updated_msg: Επιτυχής ενημέρωση του Emoji!
+      updated_msg: Επιτυχής ενημέρωση του emoji!
       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: Ο αποκλεισμός τομέα είναι υπό επεξεργασία
@@ -222,11 +271,13 @@ el:
         title: Αποκλεισμός νέου τομέα
       reject_media: Απόρριψη πολυμέσων
       reject_media_hint: Αφαιρεί τα τοπικά αποθηκευμένα αρχεία πολυμέσων και αποτρέπει τη λήψη άλλων στο μέλλον. Δεν έχει σημασία για τις αναστολές
-      severities:
-        noop: Κανένα
-        silence: Αποσιώπηση
-        suspend: Αναστολή
-      severity: Αυστηρότητα
+      reject_reports: Απόρριψη καταγγελιών
+      reject_reports_hint: Αγνόηση όσων καταγγελιών προέρχονται από αυτό τον τομέα. Δεν σχετίζεται με τις παύσεις
+      rejecting_media: απορρίπτουν αρχεία πολυμέσων
+      rejecting_reports: απορρίπτουν καταγγελίες
+      severity:
+        silence: αποσιωπημένοι
+        suspend: ανεσταλμένοι
       show:
         affected_accounts:
           one: Επηρεάζεται ένας λογαριασμός στη βάση δεδομένων
@@ -236,7 +287,6 @@ el:
           suspend: Αναίρεση αναστολής όλων των λογαριασμών του τομέα
         title: Αναίρεση αποκλεισμού για τον τομέα %{domain}
         undo: Αναίρεση
-      title: Αποκλεισμένοι τομείς
       undo: Αναίρεση
     email_domain_blocks:
       add_new: Πρόσθεση νέου
@@ -248,19 +298,47 @@ el:
         create: Πρόσθεση τομέα
         title: Νέα εγγραφή email στη μαύρη λίστα
       title: Μαύρη λίστα email
+    followers:
+      back_to_account: Επιστροφή στον λογαριασμό
+      title: Ακόλουθοι του/της %{acct}
     instances:
-      account_count: Γνωστοί λογαριασμοί
-      domain_name: Τομέας
-      reset: Επαναφορά
-      search: Αναζήτηση
+      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: Πρόσθεσε νέο ανταποκριτή (relay)
+      delete: Διαγραφή
+      description_html: Ο <strong>ομοσπονδιακός ανταποκριτής</strong> είναι ένας ενδιάμεσος εξυπηρετητής (server) που ανταλλάσσει μεγάλους όγκους δημόσιων τουτ μεταξύ εξυπηρετητών που εγγράφονται και δημοσιεύουν σε αυτόν. <strong>Βοηθάει μικρούς και μεσαίους εξυπηρετητές να ανακαλύψουν περιεχόμενο στο fediverse</strong>, που υπό άλλες συνθήκες θα χρειαζόταν κάποιους τοπικούς χρήστες που να ακολουθούν χρήστες σε απομακρυσμένους εξυπηρετητές.
+      disable: Απενεργοποίηση
+      disabled: Απενεργοποιημένο
+      enable: Ενεργοποίηση
+      enable_hint: Μόλις ενεργοποιηθεί, ο εξυπηρετητής (server) σου θα εγγραφεί σε όλα τα δημόσια τουτ αυτού του ανταποκριτή (relay) και θα αρχίσει να προωθεί τα δικά του δημόσια τουτ σε αυτόν.
+      enabled: Ενεργοποιημένο
+      inbox_url: URL ανταποκριτή
+      pending: Περιμένοντας την έγκριση του ανταποκριτή
+      save_and_enable: Αποθήκευση και ενεργοποίηση
+      setup: Όρισε μια σύνδεση ανταπόκρισης
+      status: Κατάσταση
+      title: Ανταποκριτές
     report_notes:
       created_msg: Επιτυχής δημιουργία σημείωσης καταγγελίας!
       destroyed_msg: Επιτυχής διαγραφή σημείωσης καταγγελίας!
@@ -274,32 +352,26 @@ el:
       assigned: Αρμόδιος συντονιστής
       comment:
         none: Κανένα
-      created_at: Αναφέρθηκε
-      id: ID
+      created_at: Καταγγέλθηκε
       mark_as_resolved: Σημειωμένο ως επιλυμένο
       mark_as_unresolved: Σημειωμένο ως ανεπίλυτο
       notes:
         create: Πρόσθεσε σημείωση
         create_and_resolve: Επίλυσε με σημείωση
         create_and_unresolve: Ξανάνοιξε με σημείωση
-        delete: Διέγραψε
+        delete: Διαγραφή
         placeholder: Περιέγραψε τις ενέργειες που έγιναν, ή οποιαδήποτε άλλη ενημέρωση...
       reopen: Ξανάνοιξε την καταγγελία
       report: 'Καταγγελία #%{id}'
-      report_contents: Περιεχόμενα
       reported_account: Αναφερόμενος λογαριασμός
       reported_by: Αναφέρθηκε από
       resolved: Επιλύθηκε
       resolved_msg: Η καταγγελία επιλύθηκε επιτυχώς!
-      silence_account: Αποσιώπηση λογαριασμού
       status: Κατάσταση
-      suspend_account: Ανέστειλε λογαριασμό
-      target: Αποδέκτης
       title: Αναφορές
       unassign: Αποσύνδεση
       unresolved: Άλυτη
       updated_at: Ενημερωμένη
-      view: Εμφάνιση
     settings:
       activity_api_enabled:
         desc_html: Καταμέτρηση τοπικών δημοσιεύσεων, ενεργών χρηστών και νέων εγγραφών σε εβδομαδιαίες ομαδοποιήσεις
@@ -310,12 +382,24 @@ el:
       contact_information:
         email: Επαγγελματικό email
         username: Όνομα χρήστη επικοινωνίας
+      custom_css:
+        desc_html: Τροποποίηση της εμφάνισης μέσω CSS που φορτώνεται σε κάθε σελίδα
+        title: Προσαρμοσμένο CSS
       hero:
         desc_html: Εμφανίζεται στην μπροστινή σελίδα. Συνίσταται τουλάχιστον 600x100px. Όταν λείπει, χρησιμοποιείται η μικρογραφία του κόμβου
         title: Εικόνα ήρωα
+      mascot:
+        desc_html: Εμφάνιση σε πολλαπλές σελίδες. Προτεινόμενο 293x205px τουλάχιστον. Αν δεν έχει οριστεί, χρησιμοποιεί την προεπιλεγμένη μασκότ
+        title: Εικόνα μασκότ
       peers_api_enabled:
         desc_html: Ονόματα τομέων που αυτός ο κόμβος έχει ήδη συναντήσει στο fediverse
         title: Δημοσίευση λίστας κόμβων που έχουν ανακαλυφθεί
+      preview_sensitive_media:
+        desc_html: Οι προεπισκοπήσεις συνδέσμων σε τρίτους ιστότοπους θα είναι ορατές ακόμα κι όταν το πολυμέσο έχει σημειωθεί ως ευαίσθητο
+        title: Εμφάνιση ευαίσθητων πολυμέσων στις προεπισκοπήσεις OpenGraph
+      profile_directory:
+        desc_html: Να επιτρέπεται η ανακάλυψη χρηστών
+        title: Ενεργοποίηση του καταλόγου χρηστών
       registrations:
         closed_message:
           desc_html: Εμφανίζεται στην εισαγωγική σελίδα όταν οι εγγραφές είναι κλειστές. Μπορείς να χρησιμοποιήσεις HTML tags
@@ -336,11 +420,14 @@ el:
         desc_html: Δείξε ένα σήμα προσωπικού στη σελίδα ενός χρήστη
         title: Δείξε διακριτικό προσωπικού
       site_description:
-        desc_html: Εισαγωγική παράγραφος στην αρχική σελίδα και στα meta tags. Μπορείς να χρησιμοποιήσεις HTML tags, συγκεκριμένα <code>&lt; a&gt;</code> και <code> &lt; em&gt;</code>.
+        desc_html: Εισαγωγική παράγραφος στην αρχική σελίδα. Περιέγραψε τι κάνει αυτό τον διακομιστή Mastodon διαφορετικό και ό,τι άλλο ενδιαφέρον. Μπορείς να χρησιμοποιήσεις HTML tags, συγκεκριμένα <code>&lt; a&gt;</code> και <code> &lt; em&gt;</code>.
         title: Περιγραφή κόμβου
       site_description_extended:
         desc_html: Ένα καλό μέρος για τον κώδικα δεοντολογίας, τους κανόνες, τις οδηγίες και ό,τι άλλο διαφοροποιεί τον κόμβο σου. Δέχεται και κώδικα HTML
         title: Προσαρμοσμένες εκτεταμένες πληροφορίες
+      site_short_description:
+        desc_html: Εμφανίζεται στην πλαϊνή μπάρα και στα meta tags. Περιέγραψε τι είναι το Mastodon και τι κάνει αυτό τον διακομιστή ιδιαίτερο σε μια παράγραφο. Αν μείνει κενό, θα πάρει την προκαθορισμένη περιγραφή του κόμβου.
+        title: Σύντομη περιγραφή του κόμβου
       site_terms:
         desc_html: Μπορείς να γράψεις τη δική σου πολιτική απορρήτου, όρους χρήσης ή άλλους νομικούς όρους. Μπορείς να χρησιμοποιήσεις HTML tags
         title: Προσαρμοσμένοι όροι χρήσης της υπηρεσίας
@@ -362,6 +449,7 @@ el:
       media:
         title: Πολυμέσα
       no_media: Χωρίς πολυμέσα
+      no_status_selected: Καμία δημοσίευση δεν άλλαξε αφού καμία δεν ήταν επιλεγμένη
       title: Καταστάσεις λογαριασμού
       with_media: Με πολυμέσα
     subscriptions:
@@ -371,7 +459,21 @@ el:
       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_report:
       body: Ο/Η %{reporter} κατήγγειλε τον/την %{target}
@@ -393,7 +495,7 @@ el:
     warning: Μεγάλη προσοχή με αυτά τα στοιχεία. Μην τα μοιραστείς ποτέ με κανέναν!
     your_token: Το διακριτικό πρόσβασής σου (access token)
   auth:
-    agreement_html: Με την εγγραφή σου, συμφωνείς να ακολουθείς <a href="%{rules_path}">τους κανόνες αυτού του κόμβου</a> και <a href="%{terms_path}">τους όρους χρήσης του</a>.
+    agreement_html: Επιλέγοντας το "Εγγραφή", συμφωνείς πως δέχεσαι <a href="%{rules_path}">τους κανόνες αυτού του κόμβου</a> και <a href="%{terms_path}">τους όρους χρήσης του</a>.
     change_password: Συνθηματικό
     confirm_email: Επιβεβαίωση email
     delete_account: Διαγραφή email
@@ -430,7 +532,7 @@ el:
   datetime:
     distance_in_words:
       about_x_hours: "%{count}ω"
-      about_x_months: "%{count}μη"
+      about_x_months: "%{count}μ"
       about_x_years: "%{count}ε"
       almost_x_years: "%{count}ε"
       half_a_minute: Μόλις τώρα
@@ -449,6 +551,16 @@ el:
     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': Η σελίδα που ψάχνεις δεν υπάρχει.
@@ -460,7 +572,7 @@ el:
     '500':
       content: Λυπούμαστε, κάτι πήγε στραβά από τη δική μας μεριά.
       title: Η σελίδα αυτή δεν είναι σωστή
-    noscript_html: Για να χρησιμοποιήσετε τη δικτυακή εφαρμογή του Mastodon, ενεργοποίησε την Javascript. Εναλλακτικά, δοκίμασε μια από τις <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">εφαρμογές</a> για το Mastodon στην πλατφόρμα σου.
+    noscript_html: Για να χρησιμοποιήσετε τη δικτυακή εφαρμογή του Mastodon, ενεργοποίησε την Javascript. Εναλλακτικά, δοκίμασε μια από τις <a href="%{apps_path}">εφαρμογές</a> για το Mastodon στην πλατφόρμα σου.
   exports:
     archive_takeout:
       date: Ημερομηνία
@@ -471,7 +583,9 @@ el:
       size: Μέγεθος
     blocks: Μπλοκάρεις
     csv: CSV
+    domain_blocks: Μπλοκαρίσματα κόμβων
     follows: Ακολουθείς
+    lists: Λίστες
     mutes: Αποσιωπάς
     storage: Αποθήκευση πολυμέσων
   filters:
@@ -502,10 +616,14 @@ el:
     true_privacy_html: Έχε υπ' όψιν σου πως <strong>η πραγματική ιδιωτικότητα επιτυγχάνεται μόνο με κρυπτογράφηση από άκρη σε άκρη</strong>.
     unlocked_warning_html: Μπορεί ο οποιοσδήποτε να σε ακολουθήσει και να βλέπει κατευθείαν τις ιδιωτικές ενημερώσεις σου. %{lock_link} για να αναθεωρήσεις και απορρίψεις ακόλουθους.
     unlocked_warning_title: Ο λογαριασμός σου δεν είναι κλειδωμένος
+  footer:
+    developers: Ανάπτυξη
+    more: Περισσότερα…
+    resources: Πόροι
   generic:
     changes_saved_msg: Οι αλλαγές αποθηκεύτηκαν!
-    powered_by: παρέχεται από %{link}
-    save_changes: Αποθήκευσε αλλαγές
+    copy: Αντιγραφή
+    save_changes: Αποθήκευσε τις αλλαγές
     validation_errors:
       one: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε το παρακάτω σφάλμα
       other: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε τα παρακάτω %{count} σφάλματα
@@ -540,8 +658,6 @@ el:
       expires_at: Λήγει
       uses: Χρήσεις
     title: Προσκάλεσε άτομα
-  landing_strip_html: Ο/Η <strong>%{name}</strong> είναι χρήστης στο %{link_to_root_path}. Μπορείς να ακολουθήσεις ή να αλληλεπιδράσεις μαζί τους αν έχεις λογαριασμό οπουδήποτε στο fediverse.
-  landing_strip_signup_html: Αν όχι, μπορείς να <a href="%{sign_up_path}">γραφτείς εδώ</a>.
   lists:
     errors:
       limit: Έχεις φτάσει το μέγιστο πλήθος επιτρεπτών λιστών
@@ -595,11 +711,11 @@ el:
       decimal_units:
         format: "%n%u"
         units:
-          billion: Δις.
-          million: Εκ.
-          quadrillion: Τετρ.
-          thousand: Χ.
-          trillion: Τρις.
+          billion: δις.
+          million: εκ.
+          quadrillion: τετράκις.
+          thousand: χ.
+          trillion: τρις.
   pagination:
     newer: Νεότερο
     next: Επόμενο
@@ -612,15 +728,30 @@ el:
     publishing: Δημοσίευση
     web: Διαδίκτυο
   remote_follow:
-    acct: Γράψε το ΌνομαΧρήστη@τομέας από όπου θέλεις να ακολουθήσεις
+    acct: Γράψε το ΌνομαΧρήστη@τομέα από όπου θέλεις να εκτελέσεις την ενέργεια αυτή
     missing_resource: Δεν βρέθηκε το απαιτούμενο URL ανακατεύθυνσης για το λογαριασμό σου
     no_account_html: Δεν έχεις λογαριασμό; Μπορείς <a href='%{sign_up_path}' target='_blank'>να γραφτείς εδώ</a>
     proceed: Συνέχισε για να ακολουθήσεις
-    prompt: 'Θα ακολουθήσεις:'
+    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: Φυλλομετρητής (Browser)
@@ -700,16 +831,16 @@ el:
       private: Τα μη δημόσια τουτ δεν καρφιτσώνονται
       reblog: Οι προωθήσεις δεν καρφιτσώνονται
     show_more: Δείξε περισσότερα
+    sign_in_to_participate: Εγγράφου για να συμμετάσχεις στη συζήτηση
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Μόνο ακόλουθοι
       private_long: Εμφάνιση μόνο σε ακόλουθους
       public: Δημόσιο
       public_long: Βλέπει οποιοσδήποτε
-      unlisted: Ακαταχώριστο
+      unlisted: Μη καταχωρημένο
       unlisted_long: Βλέπει οποιοσδήποτε, αλλά δεν καταχωρείται στις δημόσιες ροές
   stream_entries:
-    click_to_show: Κλικ για εμφάνιση
     pinned: Καρφιτσωμένο τουτ
     reblogged: προωθημένο
     sensitive_content: Ευαίσθητο περιεχόμενο
@@ -803,6 +934,7 @@ el:
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Βάλε τον κωδικό που δημιούργησε η εφαρμογή πιστοποίησής σου για επιβεβαίωση
     description_html: Αν ενεργοποιήσεις την <strong>πιστοποίηση 2 παραγόντων (2FA)</strong>, για να συνδεθείς θα πρέπει να έχεις το τηλέφωνό σου, που θα σου δημιουργήσει κλειδιά εισόδου.
@@ -824,6 +956,22 @@ el:
       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: Μπορείς να προσαρμόσεις το προφίλ σου ανεβάζοντας μια εικόνα εμφάνισης & επικεφαλίδας, αλλάζοντας το εμφανιζόμενο όνομά σου και άλλα. Αν θες να ελέγχεις τους νέου σου ακόλουθους πριν αυτοί σε ακολουθήσουν, μπορείς να κλειδώσεις το λογαριασμό σου.
@@ -835,7 +983,6 @@ el:
       review_preferences_action: Αλλαγή προτιμήσεων
       review_preferences_step: Σιγουρέψου πως έχεις ορίσει τις προτιμήσεις σου, όπως το ποια email θέλεις να λαμβάνεις, ή ποιο επίπεδο ιδιωτικότητας θέλεις να έχουν οι δημοσιεύσεις σου. Αν δεν σε πιάνει ναυτία, μπορείς να ενεργοποιήσεις την αυτόματη αναπαραγωγή των GIF.
       subject: Καλώς ήρθες στο Mastodon
-      tip_bridge_html: Αν έχεις έρθει από το Twitter, μπορείς να βρεις τους φίλους και τις φίλες σου στο Mastodon χρησιμοποιώντας την <a href="%{bridge_url}">βοηθητική εφαρμογή</a>. Υπόψιν πως δουλεύει μόνο αν την έχουν χρησιμοποιήσει και εκείνοι!
       tip_federated_timeline: Η ομοσπονδιακή ροή είναι μια όψη πραγματικού χρόνου στο δίκτυο του Mastodon. Παρόλα αυτά, περιλαμβάνει μόνο όσους ακολουθούν οι γείτονές σου, άρα δεν είναι πλήρης.
       tip_following: Ακολουθείς το διαχειριστή του διακομιστή σου αυτόματα. Για να βρεις περισσότερους ενδιαφέροντες ανθρώπους, έλεγξε την τοπική και την ομοσπονδιακή ροή.
       tip_local_timeline: Η τοπική ροή είναι η όψη πραγματικού χρόνου των ανθρώπων στον κόμβο %{instance}. Αυτοί είναι οι άμεσοι γείτονές σου!
@@ -843,8 +990,12 @@ el:
       tips: Συμβουλές
       title: Καλώς όρισες, %{name}!
   users:
+    follow_limit_reached: Δεν μπορείς να ακολουθήσεις περισσότερα από %{limit} άτομα
     invalid_email: Η διεύθυνση email είναι άκυρη
     invalid_otp_token: Άκυρος κωδικός πιστοποίησης 2 παραγόντων (2FA)
     otp_lost_help_html: Αν χάσεις και τα δύο, μπορείς να επικοινωνήσεις με τον/την %{email}
     seamless_external_login: Επειδή έχεις συνδεθεί μέσω τρίτης υπηρεσίας, οι ρυθμίσεις συνθηματικού και email δεν είναι διαθέσιμες.
     signed_in_as: 'Έχεις συνδεθεί ως:'
+  verification:
+    explanation_html: 'Μπορείς να <strong>πιστοποιήσεις τον εαυτό σου ως ιδιοκτήτη των συνδέσμων που εμφανίζεις στα μεταδεδομένα του προφίλ σου</strong>. Για να συμβεί αυτό, ο συνδεδεμένος ιστότοπος πρέπει να περιέχει ένα σύνδεσμο που να επιστρέφει προς το προφίλ σου στο Mastodon. Ο σύνδεσμος επιστροφής <strong>πρέπει</strong> περιέχει την ιδιότητα (attribute) <code>rel="me"</code>. Το περιεχόμενο του κειμένου δεν έχει σημασία. Για παράδειγμα:'
+    verification: Πιστοποίηση
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2b9fbca892091b11a38d4dcfae1ef34a2fa821ef..078c5b20f5bfd29f67e17ecb2a8a56a7c14f6f3c 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -5,13 +5,13 @@ en:
     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
     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.
     contact: Contact
     contact_missing: Not set
     contact_unavailable: N/A
-    description_headline: What is %{domain}?
-    domain_count_after: other instances
-    domain_count_before: Connected to
+    documentation: Documentation
     extended_description_html: |
       <h3>A good place for rules</h3>
       <p>The extended description has not been set up yet.</p>
@@ -28,25 +28,41 @@ en:
     hosted_on: Mastodon hosted on %{domain}
     learn_more: Learn more
     other_instances: Instance list
+    privacy_policy: Privacy policy
     source_code: Source code
-    status_count_after: statuses
+    status_count_after:
+      one: status
+      other: statuses
     status_count_before: Who authored
-    user_count_after: users
+    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: Followers
+    followers:
+      one: Follower
+      other: Followers
     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}
-    posts: Toots
+    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
-    remote_follow: Remote follow
     reserved_username: The username is reserved
     roles:
       admin: Admin
@@ -54,6 +70,9 @@ en:
       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!
@@ -65,14 +84,15 @@ en:
       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}
+        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
@@ -80,16 +100,19 @@ en:
       display_name: Display name
       domain: Domain
       edit: Edit
-      email: E-mail
-      email_status: E-mail Status
+      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
@@ -99,6 +122,7 @@ en:
       media_attachments: Media attachments
       memorialize: Turn into memoriam
       moderation:
+        active: Active
         all: All
         silenced: Silenced
         suspended: Suspended
@@ -106,20 +130,18 @@ en:
       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
-      order:
-        alphabetic: Alphabetic
-        most_recent: Most recent
-        title: Order
       outbox_url: Outbox URL
-      perform_full_suspension: Perform full suspension
+      perform_full_suspension: Suspend
       profile_url: Profile URL
       promote: Promote
       protocol: Protocol
       public: Public
       push_subscription_expires: PuSH subscription expires
-      redownload: Refresh avatar
+      redownload: Refresh profile
       remove_avatar: Remove avatar
+      remove_header: Remove header
       resend_confirmation:
         already_confirmed: This user is already confirmed
         send: Resend confirmation email
@@ -135,30 +157,34 @@ en:
         user: User
       salmon_url: Salmon URL
       search: Search
-      shared_inbox_url: Shared Inbox URL
+      shared_inbox_url: Shared inbox URL
       show:
-        created_reports: Reports created by this account
-        report: report
-        targeted_reports: Reports made about this account
+        created_reports: Made reports
+        targeted_reports: Reported by others
       silence: Silence
+      silenced: Silenced
       statuses: Statuses
       subscribe: Subscribe
+      suspended: Suspended
       title: Accounts
-      unconfirmed_email: Unconfirmed E-mail
+      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}"
@@ -180,6 +206,7 @@ en:
         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
@@ -206,8 +233,30 @@ en:
       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
+      add_new: Add new domain block
       created_msg: Domain block is now being processed
       destroyed_msg: Domain block has been undone
       domain: Domain
@@ -222,11 +271,13 @@ en:
         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
-      severities:
-        noop: None
-        silence: Silence
-        suspend: Suspend
-      severity: Severity
+      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
@@ -236,8 +287,7 @@ en:
           suspend: Unsuspend all existing accounts from this domain
         title: Undo domain block for %{domain}
         undo: Undo
-      title: Domain blocks
-      undo: Undo
+      undo: Undo domain block
     email_domain_blocks:
       add_new: Add new
       created_msg: Successfully added e-mail domain to blacklist
@@ -248,19 +298,47 @@ en:
         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:
-      account_count: Known accounts
-      domain_name: Domain
-      reset: Reset
-      search: Search
-      title: Known instances
+      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!
@@ -275,7 +353,6 @@ en:
       comment:
         none: None
       created_at: Reported
-      id: ID
       mark_as_resolved: Mark as resolved
       mark_as_unresolved: Mark as unresolved
       notes:
@@ -286,20 +363,15 @@ en:
         placeholder: Describe what actions have been taken, or any other related updates...
       reopen: Reopen report
       report: 'Report #%{id}'
-      report_contents: Contents
       reported_account: Reported account
       reported_by: Reported by
       resolved: Resolved
       resolved_msg: Report successfully resolved!
-      silence_account: Silence account
       status: Status
-      suspend_account: Suspend account
-      target: Target
       title: Reports
       unassign: Unassign
       unresolved: Unresolved
       updated_at: Updated
-      view: View
     settings:
       activity_api_enabled:
         desc_html: Counts of locally posted statuses, active users, and new registrations in weekly buckets
@@ -310,15 +382,24 @@ en:
       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 instance 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
       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
@@ -339,11 +420,14 @@ en:
         desc_html: Show a staff badge on a user page
         title: Show staff badge
       site_description:
-        desc_html: Introductory paragraph on the frontpage and in meta tags. You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>.
+        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
       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
         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
       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
@@ -365,6 +449,7 @@ en:
       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:
@@ -374,7 +459,21 @@ en:
       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_report:
       body: "%{reporter} has reported %{target}"
@@ -396,7 +495,7 @@ en:
     warning: Be very careful with this data. Never share it with anyone!
     your_token: Your access token
   auth:
-    agreement_html: By signing up you agree to follow <a href="%{rules_path}">the rules of the instance</a> and <a href="%{terms_path}">our terms of service</a>.
+    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>.
     change_password: Password
     confirm_email: Confirm email
     delete_account: Delete account
@@ -452,6 +551,16 @@ en:
     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_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 were looking for doesn't exist.
@@ -463,7 +572,7 @@ en:
     '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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">native apps</a> for Mastodon for your platform.
+    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
@@ -474,7 +583,9 @@ en:
       size: Size
     blocks: You block
     csv: CSV
+    domain_blocks: Domain blocks
     follows: You follow
+    lists: Lists
     mutes: You mute
     storage: Media storage
   filters:
@@ -505,9 +616,13 @@ en:
     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:
     changes_saved_msg: Changes successfully saved!
-    powered_by: powered by %{link}
+    copy: Copy
     save_changes: Save changes
     validation_errors:
       one: Something isn't quite right yet! Please review the error below
@@ -543,8 +658,6 @@ en:
       expires_at: Expires
       uses: Uses
     title: Invite people
-  landing_strip_html: "<strong>%{name}</strong> is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse."
-  landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
   lists:
     errors:
       limit: You have reached the maximum amount of lists
@@ -616,15 +729,30 @@ en:
     publishing: Publishing
     web: Web
   remote_follow:
-    acct: Enter your username@domain you want to follow from
+    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
@@ -704,6 +832,7 @@ en:
       private: Non-public toot cannot be pinned
       reblog: A boost cannot be pinned
     show_more: Show more
+    sign_in_to_participate: Sign in to participate in the conversation
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Followers-only
@@ -713,7 +842,6 @@ en:
       unlisted: Unlisted
       unlisted_long: Everyone can see, but not listed on public timelines
   stream_entries:
-    click_to_show: Click to show
     pinned: Pinned toot
     reblogged: boosted
     sensitive_content: Sensitive content
@@ -814,6 +942,7 @@ en:
   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.
@@ -835,6 +964,22 @@ en:
       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.
@@ -846,7 +991,6 @@ en:
       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_bridge_html: If you are coming from Twitter, you can find your friends on Mastodon by using the <a href="%{bridge_url}">bridge app</a>. It only works if they also used the bridge app though!
       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!
@@ -854,8 +998,12 @@ en:
       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/en_GB.yml b/config/locales/en_GB.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d9e1a256f6c9a5842d1647e5207699a27c1afc83
--- /dev/null
+++ b/config/locales/en_GB.yml
@@ -0,0 +1,2 @@
+---
+{}
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index 2f479bff64f0cada272e9323358c7faeeff2babf..aaa943185659d2eb925fd91afa38712e1375b8f5 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -5,13 +5,13 @@ eo:
     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
     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.
     contact: Kontakti
     contact_missing: Ne elektita
     contact_unavailable: Ne disponebla
-    description_headline: Kio estas %{domain}?
-    domain_count_after: aliaj nodoj
-    domain_count_before: Konektita al
+    documentation: Dokumentado
     extended_description_html: |
       <h3>Bona loko por reguloj</h3>
       <p>La detala priskribo ne estis elektita.</p>
@@ -28,25 +28,41 @@ eo:
     hosted_on: "%{domain} estas nodo de Mastodon"
     learn_more: Lerni pli
     other_instances: Listo de nodoj
+    privacy_policy: Privateca politiko
     source_code: Fontkodo
-    status_count_after: mesaĝoj
+    status_count_after:
+      one: mesaĝo
+      other: mesaĝoj
     status_count_before: Kie skribiĝis
-    user_count_after: uzantoj
+    terms: Uzkondiĉoj
+    user_count_after:
+      one: uzanto
+      other: uzantoj
     user_count_before: Hejmo de
     what_is_mastodon: Kio estas Mastodon?
   accounts:
+    choices_html: 'Proponoj de %{name}:'
     follow: Sekvi
-    followers: Sekvantoj
+    followers:
+      one: Sekvanto
+      other: Sekvantoj
     following: Sekvatoj
+    joined: Aliĝis je %{date}
+    last_active: laste aktiva
+    link_verified_on: Proprieto de ĉi tiu ligilo estis kontrolita je %{date}
     media: Aŭdovidaĵoj
     moved_html: "%{name} moviĝis al %{new_profile_link}:"
     network_hidden: Tiu informo ne estas disponebla
     nothing_here: Estas nenio ĉi tie!
     people_followed_by: Sekvatoj de %{name}
     people_who_follow: Sekvantoj de %{name}
-    posts: Mesaĝoj
+    pin_errors:
+      following: Vi devas sekvi la homon, kiun vi volas proponi
+    posts:
+      one: Mesaĝo
+      other: Mesaĝoj
+    posts_tab_heading: Mesaĝoj
     posts_with_replies: Mesaĝoj kaj respondoj
-    remote_follow: Fore sekvi
     reserved_username: La uzantnomo estas rezervita
     roles:
       admin: Administranto
@@ -99,6 +115,7 @@ eo:
       media_attachments: Ligitaj aŭdovidaĵoj
       memorialize: Ŝanĝi al memoro
       moderation:
+        active: Aktiva
         all: Ĉio
         silenced: Silentigitaj
         suspended: Haltigitaj
@@ -106,13 +123,10 @@ eo:
       moderation_notes: Kontrolaj notoj
       most_recent_activity: Lasta ago
       most_recent_ip: Lasta IP
+      no_limits_imposed: Neniu limito trudita
       not_subscribed: Ne abonita
-      order:
-        alphabetic: LaÅ­alfabete
-        most_recent: Plej lastatempa
-        title: Ordo
       outbox_url: Elira URL
-      perform_full_suspension: Tute haltigi
+      perform_full_suspension: Haltigi
       profile_url: Profila URL
       promote: Plirangigi
       protocol: Protokolo
@@ -138,11 +152,12 @@ eo:
       shared_inbox_url: URL de kunhavigita leterkesto
       show:
         created_reports: Signaloj kreitaj de ĉi tiu konto
-        report: signalo
         targeted_reports: Signaloj kreitaj de ĉi tiu konto
       silence: Kaŝi
+      silenced: Silentigita
       statuses: Mesaĝoj
       subscribe: Aboni
+      suspended: Haltigita
       title: Kontoj
       unconfirmed_email: Nekonfirmita retadreso
       undo_silenced: Malfari kaŝon
@@ -159,6 +174,7 @@ eo:
         create_domain_block: "%{name} blokis domajnon %{target}"
         create_email_domain_block: "%{name} metis en nigran liston domajnon %{target}"
         demote_user: "%{name} degradis uzanton %{target}"
+        destroy_custom_emoji: "%{name} neniigis la emoĝion %{target}"
         destroy_domain_block: "%{name} malblokis domajnon %{target}"
         destroy_email_domain_block: "%{name} metis en blankan liston domajnon %{target}"
         destroy_status: "%{name} forigis mesaĝojn de %{target}"
@@ -180,6 +196,7 @@ eo:
         unsuspend_account: "%{name} malhaltigis la konton de %{target}"
         update_custom_emoji: "%{name} ĝisdatigis emoĝion %{target}"
         update_status: "%{name} ĝisdatigis mesaĝon de %{target}"
+      deleted_status: "(forigita mesaĝo)"
       title: Kontrola protokolo
     custom_emojis:
       by_domain: Domajno
@@ -206,6 +223,28 @@ eo:
       update_failed_msg: Ĝisdatigi tiun emoĝion ne eblis
       updated_msg: Emoĝio sukcese ĝisdatigita!
       upload: Alŝuti
+    dashboard:
+      backlog: postigitaj taskoj
+      config: Agordado
+      feature_deletions: Forigo de kontoj
+      feature_invites: Invitaj ligiloj
+      feature_profile_directory: Profilujo
+      feature_registrations: Registriĝoj
+      feature_relay: Federacia ripetilo
+      features: Funkcioj
+      hidden_service: Federacio kun kaŝitaj servoj
+      open_reports: nefermitaj raportoj
+      recent_users: Lastatempaj uzantoj
+      search: Tutteksta serĉado
+      single_user_mode: Unuuzanta reĝimo
+      software: Programo
+      space: Memorspaca uzado
+      title: Kontrolpanelo
+      total_users: uzantoj sume
+      trends: Furoroj
+      week_interactions: interagoj tiusemajne
+      week_users_active: aktivaj tiusemajne
+      week_users_new: uzantoj tiusemajne
     domain_blocks:
       add_new: Aldoni novan
       created_msg: Domajna blokado en traktado
@@ -222,11 +261,6 @@ 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
-      severities:
-        noop: Nenio
-        silence: Kaŝi
-        suspend: Haltigi
-      severity: Severeco
       show:
         affected_accounts:
           one: Unu konto en la datumbazo esta influita
@@ -236,7 +270,6 @@ eo:
           suspend: Malhaltigi ĉiujn kontojn, kiuj ekzistas en ĉi tiu domajno
         title: Malfari domajnan blokadon por %{domain}
         undo: Malfari
-      title: Domajnaj blokadoj
       undo: Malfari
     email_domain_blocks:
       add_new: Aldoni novan
@@ -249,18 +282,29 @@ eo:
         title: Nova blokado de retadresa domajno
       title: Nigra listo de retadresaj domajnoj
     instances:
-      account_count: Konataj kontoj
-      domain_name: Domajno
-      reset: Restarigi
-      search: Serĉi
       title: Konataj nodoj
     invites:
+      deactivate_all: Malaktivigi ĉion
       filter:
         all: Ĉio
         available: Disponebla
         expired: Eksvalida
         title: Filtri
       title: Invitoj
+    relays:
+      add_new: Aldoni novan ripetilon
+      delete: Forigi
+      description_html: "<strong>Fratara ripetilo</strong> estas survoja servilo, kiu interŝanĝas grandan kvanton de publikaj mesaĝoj inter serviloj, kiuj abonas kaj publikigas al ĝi. <strong>Ĝi povas helpi etajn kaj mezgrandajn servilojn malkovri enhavon de la fediverse</strong>, kio normale postulus al lokaj uzantoj mane sekvi homojn de foraj serviloj."
+      disable: Malebligi
+      disabled: Malebligita
+      enable: Ebligi
+      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
+      save_and_enable: Konservi kaj ebligi
+      setup: Agordi konekton al ripetilo
+      status: Stato
+      title: Ripetiloj
     report_notes:
       created_msg: Signala noto sukcese kreita!
       destroyed_msg: Signala noto sukcese forigita!
@@ -275,7 +319,6 @@ eo:
       comment:
         none: Nenio
       created_at: Signalita
-      id: ID
       mark_as_resolved: Marki solvita
       mark_as_unresolved: Marki nesolvita
       notes:
@@ -286,20 +329,15 @@ eo:
         placeholder: Priskribu faritajn agojn, aŭ ajnan novan informon pri tiu signalo…
       reopen: Remalfermi signalon
       report: 'Signalo #%{id}'
-      report_contents: Enhavo
       reported_account: Signalita konto
       reported_by: Signalita de
       resolved: Solvita
       resolved_msg: Signalo sukcese solvita!
-      silence_account: Kaŝi konton
       status: Mesaĝoj
-      suspend_account: Haltigi konton
-      target: Celo
       title: Signaloj
       unassign: Malasigni
       unresolved: Nesolvita
       updated_at: Äœisdatigita
-      view: Vidi
     settings:
       activity_api_enabled:
         desc_html: Sumo de lokaj mesaĝoj, aktivaj uzantoj, kaj novaj registriĝoj laŭsemajne
@@ -310,12 +348,21 @@ eo:
       contact_information:
         email: Publika retadreso
         username: Kontakta uzantnomo
+      custom_css:
+        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
         title: Kapbildo
       peers_api_enabled:
         desc_html: Nomoj de domajnoj, kiujn ĉi tiu nodo renkontis en la fediverse
         title: Publikigi liston de malkovritaj nodoj
+      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
+      profile_directory:
+        desc_html: Permesi al uzantoj esti troveblaj
+        title: Ebligi la profilujon
       registrations:
         closed_message:
           desc_html: Montrita sur la hejma paĝo kiam registriĝoj estas fermitaj. Vi povas uzi HTML-etikedojn
@@ -336,11 +383,14 @@ eo:
         desc_html: Montri teaman insignon en paĝo de uzanto
         title: Montri teaman insignon
       site_description:
-        desc_html: Enkonduka alineo en la ĉefpaĝo kaj en informaj etikedoj. Vi povas uzi HTML-etikedojn, kiel <code>&lt;a&gt;</code> kaj <code>&lt;em&gt;</code>.
+        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
       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
         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
       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
@@ -362,6 +412,7 @@ eo:
       media:
         title: Aŭdovidaĵoj
       no_media: Neniu aŭdovidaĵo
+      no_status_selected: Neniu mesaĝo estis ŝanĝita ĉar neniu estis elektita
       title: Mesaĝoj de la konto
       with_media: Kun aŭdovidaĵoj
     subscriptions:
@@ -371,6 +422,12 @@ eo:
       last_delivery: Lasta livero
       title: WebSub
       topic: Temo
+    tags:
+      hide: Kaŝi de la profilujo
+      name: Kradvorto
+      title: Kradvortoj
+      unhide: Montri en la profilujo
+      visible: Videbla
     title: Administrado
   admin_mailer:
     new_report:
@@ -393,7 +450,7 @@ eo:
     warning: Estu tre atenta kun ĉi tiu datumo. Neniam diskonigu ĝin al iu ajn!
     your_token: Via alira ĵetono
   auth:
-    agreement_html: Per registriĝo, vi konsentas kun <a href="%{rules_path}">la reguloj de nia nodo</a> kaj <a href="%{terms_path}">niaj uzkondiĉoj</a>.
+    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>.
     change_password: Pasvorto
     confirm_email: Konfirmi retadreson
     delete_account: Forigi konton
@@ -449,6 +506,13 @@ eo:
     success_msg: Via konto estis sukcese forigita
     warning_html: La forigo de la enhavo estas certa nur por ĉi tiu aparta nodo. Enhavo, kiu estis disvastigita verŝajne lasos spurojn. Eksterretaj serviloj kaj serviloj, kiuj ne abonas viajn ĝisdatigojn ne ĝisdatigos siajn datumbazojn.
     warning_title: Disponebleco de disvastigita enhavo
+  directories:
+    directory: Profilujo
+    explanation: Malkovru uzantojn per iliaj interesoj
+    explore_mastodon: Esplori %{title}
+    people:
+      one: "%{count} personoj"
+      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.
@@ -462,7 +526,7 @@ eo:
       title: Ĉi tiu paĝo ne estas ĝusta
     noscript_html: |-
       Por uzi la retan aplikaĵon de Mastodon, bonvolu ebligi JavaScript. Alimaniere, provu unu el la
-      <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">operaciumaj aplikaĵoj</a> por Mastodon por via platformo.
+      <a href="%{apps_path}">operaciumaj aplikaĵoj</a> por Mastodon por via platformo.
   exports:
     archive_takeout:
       date: Dato
@@ -504,9 +568,13 @@ eo:
     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:
     changes_saved_msg: Ŝanĝoj sukcese konservitaj!
-    powered_by: povigita de %{link}
+    copy: Kopii
     save_changes: Konservi ŝanĝojn
     validation_errors:
       one: Io mise okazis! Bonvolu konsulti la suban erar-raporton
@@ -542,8 +610,6 @@ eo:
       expires_at: Eksvalidiĝas je
       uses: Uzoj
     title: Inviti homojn
-  landing_strip_html: "<strong>%{name}</strong> estas uzanto en %{link_to_root_path}. Vi povas sekvi tiun aÅ­ interagi kun tiu, se vi havas konton ie ajn en la fediverse."
-  landing_strip_signup_html: Se vi ne havas, vi povas <a href="%{sign_up_path}">registriĝi ĉi tie</a>.
   lists:
     errors:
       limit: Vi atingis la maksimuman kvanton de listoj
@@ -615,7 +681,7 @@ eo:
     publishing: Publikado
     web: Reto
   remote_follow:
-    acct: Enmetu vian uzantnomo@domajno de kie vi volas sekvi
+    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
@@ -703,6 +769,7 @@ eo:
       private: Mesaĝo nepublika ne povas esti alpinglita
       reblog: Diskonigo ne povas esti alpinglita
     show_more: Montri pli
+    sign_in_to_participate: Ensaluti por partopreni en la konversacio
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Montri nur al sekvantoj
@@ -712,7 +779,6 @@ eo:
       unlisted: Nelistigita
       unlisted_long: Ĉiuj povas vidi, sed nelistigita en publikaj tempolinioj
   stream_entries:
-    click_to_show: Alklaki por montri
     pinned: Alpinglita
     reblogged: diskonigita
     sensitive_content: Tikla enhavo
@@ -725,6 +791,7 @@ eo:
   time:
     formats:
       default: "%Y-%m-%d %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Enmetu la kodon kreitan de via aŭtentiga aplikaĵo por konfirmi
     description_html: Se vi ebligas <strong>dufaktoran aŭtentigon</strong>, vi bezonos vian poŝtelefonon por ensaluti, ĉar ĝi kreos nombrojn, kiujn vi devos enmeti.
@@ -757,7 +824,6 @@ eo:
       review_preferences_action: Ŝanĝi preferojn
       review_preferences_step: Estu certa ke vi agordis viajn preferojn, kiel kiujn retmesaĝojn vi ŝatus ricevi, aŭ kiun dekomencan privatecan nivelon vi ŝatus ke viaj mesaĝoj havu. Se tio ne ĝenas vin, vi povas ebligi aŭtomatan ekigon de GIF-oj.
       subject: Bonvenon en Mastodon
-      tip_bridge_html: Se vi venas de Twitter, vi povas trovi viajn amikojn en Mastodon per uzo de la <a href="%{bridge_url}">ponta aplikaĵo</a>. Tamen, tio funkcias nur se ankaŭ ili uzis la pontan aplikaĵon!
       tip_federated_timeline: La fratara tempolinio estas antaŭvido de la reto de Mastodon. Sed ĝi enhavas nur homojn, kiuj estas sekvataj de aliaj homoj de via nodo, do ĝi ne estas kompleta.
       tip_following: Vi dekomence sekvas la administrantojn de via servilo. Por trovi pli da interesaj homoj, rigardu la lokan kaj frataran tempoliniojn.
       tip_local_timeline: La loka tempolinio estas antaŭvido de la homoj en %{instance}. Ĉi tiuj estas viaj apudaj najbaroj!
@@ -765,8 +831,11 @@ eo:
       tips: Konsiloj
       title: Bonvenon, %{name}!
   users:
+    follow_limit_reached: Vi ne povas sekvi pli da %{limit} homojn
     invalid_email: La retadreso estas nevalida
     invalid_otp_token: Nevalida kodo de dufaktora aÅ­tentigo
     otp_lost_help_html: Se vi perdas aliron al ambaÅ­, vi povas kontakti %{email}
     seamless_external_login: Vi estas ensalutinta per ekstera servo, do pasvortaj kaj retadresaj agordoj ne estas disponeblaj.
     signed_in_as: 'Ensalutinta kiel:'
+  verification:
+    verification: Kontrolo
diff --git a/config/locales/es.yml b/config/locales/es.yml
index de5dac5a41e841c6e2b839f30f3063b440386445..e3106291d9517497bf1754aa509a282f91618164 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -5,13 +5,13 @@ es:
     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
     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
-    description_headline: "¿Qué es %{domain}?"
-    domain_count_after: otras instancias
-    domain_count_before: Conectado a
+    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>
@@ -28,27 +28,44 @@ es:
     hosted_on: Mastodon hosteado en %{domain}
     learn_more: Aprende más
     other_instances: Otras instancias
+    privacy_policy: Política de privacidad
     source_code: Código fuente
-    status_count_after: estados
+    status_count_after:
+      one: estado
+      other: estados
     status_count_before: Qué han escrito
-    user_count_after: usuarios registrados
+    terms: Condiciones de servicio
+    user_count_after:
+      one: usuario
+      other: usuarios
     user_count_before: Tenemos
     what_is_mastodon: "¿Qué es Mastodon?"
   accounts:
+    choices_html: 'Elecciones de %{name}:'
     follow: Seguir
-    followers: Seguidores
+    followers:
+      one: Seguidor
+      other: Seguidores
     following: Siguiendo
+    joined: Se unió el %{date}
+    link_verified_on: La propiedad de este vínculo fue verificada el %{date}
     media: Media
     moved_html: "%{name} se ha trasladado a %{new_profile_link}:"
+    network_hidden: Esta información no está disponible
     nothing_here: "¡No hay nada aquí!"
     people_followed_by: Usuarios a quien %{name} sigue
     people_who_follow: Usuarios que siguen a %{name}
-    posts: Toots
+    pin_errors:
+      following: Debes estar siguiendo a la persona a la que quieres aprobar
+    posts:
+      one: Toot
+      other: Toots
+    posts_tab_heading: Toots
     posts_with_replies: Toots con respuestas
-    remote_follow: Seguir
     reserved_username: El nombre de usuario está reservado
     roles:
       admin: Administrador
+      bot: Bot
       moderator: Moderador
     unfollow: Dejar de seguir
   admin:
@@ -104,13 +121,10 @@ es:
       moderation_notes: Notas de moderación
       most_recent_activity: Actividad más reciente
       most_recent_ip: IP más reciente
+      no_limits_imposed: Sin límites impuestos
       not_subscribed: No se está suscrito
-      order:
-        alphabetic: Alfabético
-        most_recent: Más reciente
-        title: Orden
       outbox_url: URL de bandeja de salida
-      perform_full_suspension: Performar suspensión completa
+      perform_full_suspension: Suspender
       profile_url: URL del perfil
       promote: Promocionar
       protocol: Protocolo
@@ -121,7 +135,7 @@ es:
       resend_confirmation:
         already_confirmed: Este usuario ya está confirmado
         send: Reenviar el correo electrónico de confirmación
-        success: "¡Correo electrónico de confirmación enviado con éxito"
+        success: "¡Correo electrónico de confirmación enviado con éxito!"
       reset: Reiniciar
       reset_password: Reiniciar contraseña
       resubscribe: Re-suscribir
@@ -136,11 +150,12 @@ es:
       shared_inbox_url: URL de bandeja compartida
       show:
         created_reports: Reportes hechos por esta cuenta
-        report: reportar
         targeted_reports: Reportes hechos sobre esta cuenta
       silence: Silenciar
+      silenced: Silenciado
       statuses: Estados
       subscribe: Suscribir
+      suspended: Susependido
       title: Cuentas
       unconfirmed_email: Correo electrónico sin confirmar
       undo_silenced: Des-silenciar
@@ -157,6 +172,7 @@ es:
         create_domain_block: "%{name} bloqueó el dominio %{target}"
         create_email_domain_block: "%{name} puso en lista negra el dominio de correos %{target}"
         demote_user: "%{name} degradó al usuario %{target}"
+        destroy_custom_emoji: "%{name} destruyó el emoji %{target}"
         destroy_domain_block: "%{name} desbloqueó el dominio %{target}"
         destroy_email_domain_block: "%{name} puso en lista blanca el dominio de correos %{target}"
         destroy_status: "%{name} eliminó el estado de %{target}"
@@ -178,6 +194,7 @@ es:
         unsuspend_account: "%{name} desactivó la suspensión de la cuenta de %{target}"
         update_custom_emoji: "%{name} actualizó el emoji %{target}"
         update_status: "%{name} actualizó el estado de %{target}"
+      deleted_status: "(estado borrado)"
       title: Log de auditoría
     custom_emojis:
       by_domain: Dominio
@@ -204,6 +221,27 @@ es:
       update_failed_msg: No se pudo actualizar ese emoji
       updated_msg: "¡Emoji actualizado con éxito!"
       upload: Subir
+    dashboard:
+      backlog: trabajos de backlog
+      config: Configuración
+      feature_deletions: Borrados de cuenta
+      feature_invites: Enlaces de invitación
+      feature_registrations: Registros
+      feature_relay: Relés de federación
+      features: Características
+      hidden_service: Federación con servicios ocultos
+      open_reports: informes abiertos
+      recent_users: Usuarios recientes
+      search: Búsqueda por texto completo
+      single_user_mode: Modo único usuario
+      software: Software
+      space: Uso de almacenamiento
+      title: Tablero
+      total_users: usuarios en total
+      trends: Tendencias
+      week_interactions: interacciones esta semana
+      week_users_active: activo esta semana
+      week_users_new: usuarios esta semana
     domain_blocks:
       add_new: Añadir nuevo
       created_msg: El bloque de dominio está siendo procesado
@@ -220,11 +258,8 @@ es:
         title: Nuevo bloque de dominio
       reject_media: Rechazar archivos multimedia
       reject_media_hint: Remueve localmente archivos multimedia almacenados para descargar cualquiera en el futuro. Irrelevante para suspensiones
-      severities:
-        noop: Ninguno
-        silence: Silenciar
-        suspend: Suspender
-      severity: Severidad
+      reject_reports: Rechazar informes
+      reject_reports_hint: Ignore todos los reportes de este dominio. Irrelevante para suspensiones
       show:
         affected_accounts:
           one: Una cuenta en la base de datos afectada
@@ -234,7 +269,6 @@ es:
           suspend: Des-suspender todas las cuentas existentes de este dominio
         title: Deshacer bloque de dominio para %{domain}
         undo: Deshacer
-      title: Bloques de Dominio
       undo: Deshacer
     email_domain_blocks:
       add_new: Añadir nuevo
@@ -247,18 +281,30 @@ es:
         title: Nueva entrada en la lista negra de correo
       title: Lista negra de correo
     instances:
-      account_count: Cuentas conocidas
-      domain_name: Dominio
-      reset: Reiniciar
-      search: Buscar
       title: Instancias conocidas
     invites:
+      deactivate_all: Desactivar todos
       filter:
         all: Todas
         available: Disponibles
         expired: Expiradas
         title: Filtrar
       title: Invitaciones
+    relays:
+      add_new: Añadir un nuevo relés
+      delete: Borrar
+      description_html: Un <strong>relés de federation</strong> es un servidor intermedio que intercambia grandes volúmenes de toots públicos entre servidores que se suscriben y publican en él. <strong>Puede ayudar a servidores pequeños y medianos a descubir contenido del fediverso</strong>, que de otra manera requeriría que los usuarios locales siguiesen manialmente a personas de servidores remotos.
+      disable: Deshabilitar
+      disabled: Deshabilitado
+      enable: Hablitar
+      enable_hint: Una vez conectado, tu servidor se suscribirá a todos los toots públicos de este relés, y comenzará a enviar los toots públicos de este servidor hacia él.
+      enabled: Habilitado
+      inbox_url: URL del relés
+      pending: Esperando la aprobación del relés
+      save_and_enable: Guardar y conectar
+      setup: Preparar una conexión de relés
+      status: Estado
+      title: Releses
     report_notes:
       created_msg: "¡El registro de la denuncia se ha creado correctamente!"
       destroyed_msg: "¡El registro de la denuncia se ha borrado correctamente!"
@@ -273,7 +319,6 @@ es:
       comment:
         none: Ninguno
       created_at: Denunciado
-      id: ID
       mark_as_resolved: Marcar como resuelto
       mark_as_unresolved: Marcar como no resuelto
       notes:
@@ -284,20 +329,15 @@ es:
         placeholder: Especificar qué acciones se han tomado o cualquier otra novedad respecto a esta denuncia…
       reopen: Reabrir denuncia
       report: 'Reportar #%{id}'
-      report_contents: Contenido
       reported_account: Cuenta reportada
       reported_by: Reportado por
       resolved: Resuelto
       resolved_msg: "¡La denuncia se ha resuelto correctamente!"
-      silence_account: Silenciar cuenta
       status: Estado
-      suspend_account: Suspender cuenta
-      target: Objetivo
       title: Reportes
       unassign: Desasignar
       unresolved: No resuelto
       updated_at: Actualizado
-      view: Ver
     settings:
       activity_api_enabled:
         desc_html: Conteo de estados publicados localmente, usuarios activos, y nuevos registros en  periodos semanales
@@ -308,12 +348,21 @@ es:
       contact_information:
         email: Correo de trabajo
         username: Nombre de usuario
+      custom_css:
+        desc_html: Modificar el aspecto con CSS cargado en cada página
+        title: CSS personalizado
       hero:
         desc_html: Mostrado en la página principal. Recomendable al menos 600x100px. Por defecto se establece a la miniatura de la instancia
         title: Imagen de portada
+      mascot:
+        desc_html: Mostrado en múltiples páginas. Se recomienda un tamaño mínimo de 293x205px. Cuando no se especifica, se muestra la mascota por defecto
+        title: Imagen de la mascota
       peers_api_enabled:
         desc_html: Nombres de dominio que esta instancia ha encontrado en el fediverso
         title: Publicar lista de instancias descubiertas
+      preview_sensitive_media:
+        desc_html: Los enlaces de vistas previas en otras web mostrarán una miniatura incluso si el medio está marcado como contenido sensible
+        title: Mostrar contenido sensible en previews de OpenGraph
       registrations:
         closed_message:
           desc_html: Se muestra en la portada cuando los registros están cerrados. Puedes usar tags HTML
@@ -339,6 +388,9 @@ es:
       site_description_extended:
         desc_html: Un buen lugar para tu código de conducta, reglas, guías y otras cosas que estén impuestas aparte en tu instancia. Puedes usar tags HTML
         title: Información extendida personalizada
+      site_short_description:
+        desc_html: Mostrado en la barra lateral y las etiquetas de metadatos. Describe lo que es Mastodon y qué hace especial a este servidor en un solo párrafo. si está vacío, pone por defecto la descripción de la instancia.
+        title: Descripción corta de la instancia
       site_terms:
         desc_html: Puedes escribir tus propias políticas de privacidad, términos de servicio u otras legalidades. Puedes usar tags HTML
         title: Términos de servicio personalizados
@@ -360,6 +412,7 @@ es:
       media:
         title: Multimedia
       no_media: No hay multimedia
+      no_status_selected: No se cambió ningún estado al no seleccionar ninguno
       title: Estado de las cuentas
       with_media: Con multimedia
     subscriptions:
@@ -391,7 +444,7 @@ es:
     warning: Ten mucho cuidado con estos datos. ¡No los compartas con nadie!
     your_token: Tu token de acceso
   auth:
-    agreement_html: Al registrarte, acepta seguir <a href="%{rules_path}">las reglas de la instancia</a> y <a href="%{terms_path}">nuestros términos de servicio</a>.
+    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
     confirm_email: Confirmar email
     delete_account: Borrar cuenta
@@ -458,7 +511,7 @@ es:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">aplicaciones nativas</a> para Mastodon para tu plataforma.
+    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.
   exports:
     archive_takeout:
       date: Fecha
@@ -472,6 +525,22 @@ es:
     follows: Personas que sigues
     mutes: Tienes en silencio
     storage: Almacenamiento
+  filters:
+    contexts:
+      home: Timeline propio
+      notifications: Notificaciones
+      public: Timeline público
+      thread: Conversaciones
+    edit:
+      title: Editar filtro
+    errors:
+      invalid_context: Se suminstró un contexto inválido o vacío
+      invalid_irreversible: El filtrado irreversible solo funciona con los contextos propios o de notificaciones
+    index:
+      delete: Borrar
+      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.
@@ -484,9 +553,13 @@ es:
     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:
     changes_saved_msg: "¡Cambios guardados con éxito!"
-    powered_by: gracias a %{link}
+    copy: Copiar
     save_changes: Guardar cambios
     validation_errors:
       one: "¡Algo no está bien! Por favor, revisa el error"
@@ -499,7 +572,7 @@ es:
       following: Lista de seguidos
       muting: Lista de silenciados
     upload: Cargar
-  in_memoriam_html: In Memoriam.
+  in_memoriam_html: En memoria.
   invites:
     delete: Desactivar
     expired: Expiradas
@@ -512,6 +585,7 @@ es:
       '86400': 1 día
     expires_in_prompt: Nunca
     generate: Generar
+    invited_by: 'Fuiste invitado por:'
     max_uses:
       one: 1 uso
       other: "%{count} usos"
@@ -521,8 +595,6 @@ es:
       expires_at: Expira
       uses: Usos
     title: Invitar a gente
-  landing_strip_html: "<strong>%{name}</strong> es un usuario en %{link_to_root_path}. Puedes seguirlo(a) o interactuar con el o ella si tienes una cuenta en cualquier parte del fediverse."
-  landing_strip_signup_html: Si no tienes una, puedes <a href="%{sign_up_path}">registrarte aquí</a>.
   lists:
     errors:
       limit: Has alcanzado la cantidad máxima de listas
@@ -596,6 +668,7 @@ es:
   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
+    no_account_html: "¿No tienes una cuenta? Puedes <a href='%{sign_up_path}' target='_blank'>registrarte aqui</a>"
     proceed: Proceder a seguir
     prompt: 'Vas a seguir a:'
   remote_unfollow:
@@ -667,10 +740,12 @@ es:
       video:
         one: "%{count} vídeo"
         other: "%{count} vídeos"
+    boosted_from_html: Impulsado desde %{acct_link}
     content_warning: 'Alerta de contenido: %{warning}'
     disallowed_hashtags:
       one: 'contenía un hashtag no permitido: %{tags}'
       other: 'contenía los hashtags no permitidos: %{tags}'
+    language_detection: Detección automática de idioma
     open_in_web: Abrir en web
     over_character_limit: Límite de caracteres de %{max} superado
     pin_errors:
@@ -679,6 +754,7 @@ es:
       private: Los toots no-públicos no pueden fijarse
       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
@@ -688,7 +764,6 @@ es:
       unlisted: Público, pero no mostrar en la historia federada
       unlisted_long: Todos pueden ver, pero no está listado en las líneas de tiempo públicas
   stream_entries:
-    click_to_show: Click para mostrar
     pinned: Toot fijado
     reblogged: retooteado
     sensitive_content: Contenido sensible
@@ -697,9 +772,11 @@ es:
   themes:
     contrast: Alto contraste
     default: Mastodon
+    mastodon-light: Mastodon (claro)
   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.
@@ -732,7 +809,6 @@ es:
       review_preferences_action: Cambiar preferencias
       review_preferences_step: Asegúrate de poner tus preferencias, como que correos te gustaría recibir, o que nivel de privacidad te gustaría que tus publicaciones tengan por defecto. Si no tienes mareos, podrías elegir habilitar la reproducción automática de "GIFs".
       subject: Bienvenido a Mastodon
-      tip_bridge_html: Si esta viniendo desde Twitter, puedes encontrar a tus amigos en Mastodon usando la <a href="%{bridge_url}">aplicación puente</a>. Aunque solo funciona si ellos también usaron la aplicación puente!
       tip_federated_timeline: La línea de tiempo federada es una vista de la red de Mastodon. Pero solo incluye gente que tus vecinos están siguiendo, así que no está completa.
       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!
@@ -740,7 +816,12 @@ es:
       tips: Tips
       title: Te damos la bienvenida a bordo, %{name}!
   users:
+    follow_limit_reached: No puedes seguir a más de %{limit} personas
     invalid_email: La dirección de correo es incorrecta
     invalid_otp_token: Código de dos factores incorrecto
+    otp_lost_help_html: Si perdiste al acceso a ambos, puedes ponerte en contancto con %{email}
     seamless_external_login: Has iniciado sesión desde un servicio externo, así que los ajustes de contraseña y correo no están disponibles.
     signed_in_as: 'Sesión iniciada como:'
+  verification:
+    explanation_html: 'Puedes <strong> verificarte a ti mismo como el dueño de los links en los metadatos de tu perfil </strong>. Para eso, el sitio vinculado debe contener un vínculo a tu perfil de Mastodon. El vínculo en tu sitio <strong> debe </strong> tener un atributo <code> rel="me"</code>. El texto del vínculo no importa. Aquí un ejemplo:'
+    verification: Verificación
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index 514c9cc57084f169b0c569de07ab753f16077cec..cae83e158d0bb02fb67c1b9efaa181d86bf7e911 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -5,13 +5,13 @@ eu:
     about_mastodon_html: Mastodon web protokolo ireki eta libreak darabiltzan gizarte sare bat da. E-mail sarea bezala deszentralizatua da.
     about_this: Honi buruz
     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.
     contact: Kontaktua
     contact_missing: Ezarri gabe
     contact_unavailable: E/E
-    description_headline: Zer da %{domain}?
-    domain_count_after: instantzia desberdinetara
-    domain_count_before: Konektatuta
+    documentation: Dokumentazioa
     extended_description_html: |
       <h3>Arauentzako toki egoki bat</h3>
       <p>Azalpen luzea ez da ezarri oraindik.</p>
@@ -28,25 +28,41 @@ eu:
     hosted_on: Mastodon %{domain} domeinuan ostatatua
     learn_more: Ikasi gehiago
     other_instances: Instantzien zerrenda
+    privacy_policy: Pribatutasun politika
     source_code: Iturburu kodea
-    status_count_after: mezu idatzi dituzte
+    status_count_after:
+      one: mezu
+      other: mezu
     status_count_before: Hauek
-    user_count_after: erabiltzaile daude
+    terms: Erabilera baldintzak
+    user_count_after:
+      one: erabiltzaile
+      other: erabiltzaile
     user_count_before: Hemen
     what_is_mastodon: Zer da Mastodon?
   accounts:
+    choices_html: "%{name}(r)en aukerak:"
     follow: Jarraitu
-    followers: Jarraitzaile
+    followers:
+      one: Jarraitzaile
+      other: jarraitzaile
     following: Jarraitzen
+    joined: "%{date}(e)an elkartua"
+    last_active: azkenekoz aktiboa
+    link_verified_on: 'Esteka honen jabetzaren egiaztaketa data: %{date}'
     media: Multimedia
     moved_html: "%{name} hona lekualdatu da %{new_profile_link}:"
     network_hidden: Informazio hau ez dago eskuragarri
     nothing_here: Ez dago ezer hemen!
     people_followed_by: "%{name}(e)k jarraitzen dituenak"
     people_who_follow: "%{name} jarraitzen dutenak"
-    posts: Toot-ak
+    pin_errors:
+      following: Onetsi nahi duzun pertsona aurretik jarraitu behar duzu
+    posts:
+      one: Toot
+      other: Toot
+    posts_tab_heading: Tootak
     posts_with_replies: Toot eta erantzunak
-    remote_follow: Jarraitu urrunetik
     reserved_username: Erabiltzaile-izena erreserbatuta dago
     roles:
       admin: Administratzailea
@@ -54,6 +70,9 @@ eu:
       moderator: Moderatzailea
     unfollow: Utzi jarraitzeari
   admin:
+    account_actions:
+      action: Burutu ekintza
+      title: Burutu moderazio ekintza %{acct} kontuan
     account_moderation_notes:
       create: Sortu oharra
       created_msg: Moderazio oharra ongi sortu da!
@@ -88,6 +107,7 @@ eu:
       followers: Jarraitzaileak
       followers_url: Jarraitzaileen URL-a
       follows: Jarraitzen du
+      header: Goiburua
       inbox_url: Sarrera ontziaren URL-a
       ip: IP
       location:
@@ -99,6 +119,7 @@ eu:
       media_attachments: Multimedia eranskinak
       memorialize: Bihurtu memoriala
       moderation:
+        active: Aktiboa
         all: Denak
         silenced: Isilarazita
         suspended: Kanporatua
@@ -106,13 +127,10 @@ eu:
       moderation_notes: Moderazio oharrak
       most_recent_activity: Azken jarduera
       most_recent_ip: Azken IP-a
+      no_limits_imposed: Ez da mugarik ezarri
       not_subscribed: Harpidetu gabe
-      order:
-        alphabetic: Alfabetikoa
-        most_recent: Azkena
-        title: Ordena
       outbox_url: Irteera ontziaren URL-a
-      perform_full_suspension: Aplikatu kanporatze osoa
+      perform_full_suspension: Kanporatu
       profile_url: Profilaren URL-a
       promote: Sustatu
       protocol: Protokoloa
@@ -120,6 +138,7 @@ eu:
       push_subscription_expires: Push harpidetzaren iraugitzea
       redownload: Freskatu abatarra
       remove_avatar: Kendu abatarra
+      remove_header: Kendu goiburua
       resend_confirmation:
         already_confirmed: Erabiltzaile hau berretsita dago
         send: Birbidali baieztapen e-maila
@@ -138,11 +157,12 @@ eu:
       shared_inbox_url: Partekatutako sarrera ontziaren URL-a
       show:
         created_reports: Kontu honek sortutako txostenak
-        report: salatu
         targeted_reports: Kontu honek egindako salaketak
       silence: Isilarazi
+      silenced: Isilarazita
       statuses: Mezuak
       subscribe: Harpidetu
+      suspended: Kanporatuta
       title: Kontuak
       unconfirmed_email: Baieztatu gabeko e-mail helbidea
       undo_silenced: Utzi isilarazteari
@@ -155,10 +175,12 @@ eu:
         assigned_to_self_report: "%{name}(e)k %{target} salaketa bere buruari esleitu dio"
         change_email_user: "%{name}(e)k %{target}(r)en e-mail helbidea aldatu du"
         confirm_user: "%{name}(e)k %{target}(r)en e-mail helbidea berretsi du"
+        create_account_warning: "%{name}-k abisua bidali dio %{target}-ri"
         create_custom_emoji: "%{name}(e)k emoji berria kargatu du %{target}"
         create_domain_block: "%{name}(e)k %{target} domeinua blokeatu du"
         create_email_domain_block: "%{name}(e)k %{target} e-mail helbideen domeinua zerrenda beltzean sartu du"
         demote_user: "%{name}(e)k %{target} mailaz jaitsi du"
+        destroy_custom_emoji: "%{name} erabiltzaileak %{target} emojia suntsitu du"
         destroy_domain_block: "%{name}(e)k %{target} domeinua desblokeatu du"
         destroy_email_domain_block: "%{name}(e)k %{target} e-mail helbideen domeinua zerrenda zurian sartu du"
         destroy_status: "%{name}(e)k %{target}(e)n egoera kendu du"
@@ -180,6 +202,7 @@ eu:
         unsuspend_account: "%{name}(e)k %{target} kontuaren kanporaketa atzera bota du"
         update_custom_emoji: "%{name}(e)k %{target} emoji-a eguneratu du"
         update_status: "%{name} (e)k %{target}(r)en mezua aldatu du"
+      deleted_status: "(ezabatutako mezua)"
       title: Auditoria-egunkaria
     custom_emojis:
       by_domain: Domeinua
@@ -206,6 +229,28 @@ eu:
       update_failed_msg: Ezin izan da emoji hori eguneratu
       updated_msg: Emoji-a ongi eguneratu da!
       upload: Igo
+    dashboard:
+      backlog: aurreikusitako lanak
+      config: Konfigurazioa
+      feature_deletions: Kontu ezabaketak
+      feature_invites: Gonbidapen estekak
+      feature_profile_directory: Profil-direktorioa
+      feature_registrations: Izen emateak
+      feature_relay: Federazio haria
+      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
+      space: Espazio erabilera
+      title: Kontrol panela
+      total_users: erabiltzaile guztira
+      trends: Joerak
+      week_interactions: interakzio aste honetan
+      week_users_active: aktibo aste honetan
+      week_users_new: erabiltzaile aste honetan
     domain_blocks:
       add_new: Gehitu berria
       created_msg: Domeinuaren blokeoa orain prozesatzen ari da
@@ -222,11 +267,8 @@ eu:
         title: Domeinu 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
-      severities:
-        noop: Bat ere ez
-        silence: Isilarazi
-        suspend: Kanporatu
-      severity: Larritasuna
+      reject_reports: Errefusatu salaketak
+      reject_reports_hint: Ezikusi domeinu honetatik jasotako salaketak. Kanporatzeentzako garrantzirik gabekoa
       show:
         affected_accounts:
           one: Datu-baseko kontu bati eragiten dio
@@ -236,7 +278,6 @@ eu:
           suspend: Kendu kanporatzeko agindua domeinu honetako kontu guztiei
         title: Desegin %{domain} domeinuko blokeoa
         undo: Desegin
-      title: Domeinuen blokeoak
       undo: Desegin
     email_domain_blocks:
       add_new: Gehitu berria
@@ -248,19 +289,34 @@ eu:
         create: Gehitu domeinua
         title: Sarrera berria e-mail zerrenda beltzean
       title: E-mail zerrenda beltza
+    followers:
+      back_to_account: Itzuli kontura
+      title: "%{acct} kontuaren jarraitzaileak"
     instances:
-      account_count: Kontu ezagunak
-      domain_name: Domeinua
-      reset: Berrezarri
-      search: Bilatu
       title: Instantzia ezagunak
     invites:
+      deactivate_all: Desgaitu guztiak
       filter:
         all: Denak
         available: Eskuragarri
         expired: Iraungitua
         title: Iragazi
       title: Gonbidapenak
+    relays:
+      add_new: Gehitu hari berria
+      delete: Ezabatu
+      description_html: "<strong>Federazio errele</strong> bat zerbitzari tartekari bat da, bertara harpidetutako eta bertan argitaratzen duten zerbitzarien artean toot publiko kopuru handiak banatzen ditu. <strong>Zerbitzari txiki eta ertainei Fedibertsoko edukia aurkitzen laguntzen die</strong>, bestela erabiltzaile lokalek eskuz jarraitu beharko lituzkete urruneko zerbitzarietako erabiltzaileak."
+      disable: Desgaitu
+      disabled: Desgaituta
+      enable: Gaitu
+      enable_hint: Behin gaituta, zure zerbitzaria errele honetako toot publiko guztietara harpidetuko da, eta zerbitzari honetako toot publikoak errelera bidaltzen hasiko da.
+      enabled: Gaituta
+      inbox_url: Errelearen URLa
+      pending: Erreleak onartzearen zain
+      save_and_enable: Gorde eta gaitu
+      setup: Ezarri errele konexio bat
+      status: Mezuak
+      title: Erreleak
     report_notes:
       created_msg: Salaketa oharra ongi sortu da!
       destroyed_msg: Salaketa oharra ongi ezabatu da!
@@ -275,7 +331,6 @@ eu:
       comment:
         none: Bat ere ez
       created_at: Salatua
-      id: ID
       mark_as_resolved: Markatu konpondutako gisa
       mark_as_unresolved: Markatu konpondu gabeko gisa
       notes:
@@ -286,20 +341,15 @@ eu:
         placeholder: Azaldu hartutako neurriak, edo erlazioa duten bestelako berriak...
       reopen: Berrireki salaketa
       report: 'Salaketa #%{id}'
-      report_contents: Edukiak
       reported_account: Salatutako kontua
       reported_by: Salatzailea
       resolved: Konponduta
       resolved_msg: Salaketa ongi konpondu da!
-      silence_account: Isilarazi kontua
       status: Mezua
-      suspend_account: Kanporatu kontua
-      target: Helburua
       title: Salaketak
       unassign: Kendu esleipena
       unresolved: Konpondu gabea
       updated_at: Eguneratua
-      view: Ikusi
     settings:
       activity_api_enabled:
         desc_html: Lokalki bidalitako mezu kopurua, erabiltzaile aktiboak, eta izen emate berriak asteko
@@ -310,12 +360,24 @@ eu:
       contact_information:
         email: Laneko e-mail helbidea
         username: Kontaktuaren erabiltzaile-izena
+      custom_css:
+        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
         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
+      preview_sensitive_media:
+        desc_html: Beste webguneetako esteken aurrebistak iruditxoa izango du multimedia hunkigarri gisa markatzen bada ere
+        title: Erakutsi multimedia hunkigarria OpenGraph aurrebistetan
+      profile_directory:
+        desc_html: Baimendu erabiltzaileak aurkigarriak izatea
+        title: Gaitu profil-direktorioa
       registrations:
         closed_message:
           desc_html: Azaleko orrian bistaratua izen ematea ixten denean. HTML etiketak erabili ditzakezu
@@ -336,11 +398,14 @@ eu:
         desc_html: Erakutsi langile banda erabiltzailearen orrian
         title: Erakutsi langile banda
       site_description:
-        desc_html: Azaleko orrian eta meta etiketetan agertuko den sarrera paragrafoa. HTML etiketak erabili ditzakezu, zehazki <code>&lt;a&gt;</code> eta <code>&lt;em&gt;</code>.
+        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
       site_description_extended:
         desc_html: Zure jokabide-koderako  toki on bat, arauak, gidalerroak eta zure instantzia 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
       site_terms:
         desc_html: Zure pribatutasun politika, erabilera baldintzak eta bestelako testu legalak idatzi ditzakezu. HTML etiketak erabili ditzakezu
         title: Erabilera baldintza pertsonalizatuak
@@ -362,6 +427,7 @@ eu:
       media:
         title: Multimedia
       no_media: Multimediarik ez
+      no_status_selected: Ez da mezurik aldatu ez delako mezurik aukeratu
       title: Kontuaren mezuak
       with_media: Multimediarekin
     subscriptions:
@@ -371,7 +437,21 @@ eu:
       last_delivery: Azken bidalketa
       title: WebSub
       topic: Mintzagaia
+    tags:
+      accounts: Kontuak
+      hidden: Ezkutatuta
+      hide: Ezkutatu direktoriotik
+      name: Traola
+      title: Traolak
+      unhide: Erakutsi direktorioan
+      visible: Ikusgai
     title: Administrazioa
+    warning_presets:
+      add_new: Gehitu berria
+      delete: Ezabatu
+      edit: Editatu
+      edit_preset: Editatu abisu aurre-ezarpena
+      title: Kudeatu abisu aurre-ezarpenak
   admin_mailer:
     new_report:
       body: "%{reporter}(e)k %{target} salatu du"
@@ -393,7 +473,7 @@ eu:
     warning: Kontuz datu hauekin, ez partekatu inoiz inorekin!
     your_token: Zure sarbide token-a
   auth:
-    agreement_html: Izena emanez<a href="%{rules_path}">instantziaren arauak</a> eta <a href="%{terms_path}">erabilera baldintzak</a> onartzen dituzu.
+    agreement_html: '"Izena eman" botoia sakatzean <a href="%{rules_path}">instantziaren arauak</a> eta <a href="%{terms_path}">erabilera baldintzak</a> onartzen dituzu.'
     change_password: Pasahitza
     confirm_email: Berretsi e-mail helbidea
     delete_account: Ezabatu kontua
@@ -449,6 +529,13 @@ eu:
     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_title: Sakabanatutako edukiaren eskuragarritasuna
+  directories:
+    directory: Profilen direktorioa
+    explanation: Deskubritu erabiltzaileak interesen arabera
+    explore_mastodon: Esploratu %{title}
+    people:
+      one: pertsona %{count}
+      other: "%{count} pertsona"
   errors:
     '403': Ez duzu orri hau ikusteko baimenik.
     '404': Bilatu duzun orria ez da existitzen.
@@ -460,7 +547,7 @@ eu:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">aplikazio natibo</a>ren bat.
+    noscript_html: Mastodon web aplikazioa erabiltzeko, gaitu JavaScript. Bestela, probatu Mastodon plataformarako <a href="%{apps_path}">aplikazio natibo</a>ren bat.
   exports:
     archive_takeout:
       date: Data
@@ -474,6 +561,22 @@ eu:
     follows: Zuk jarraitutakoak
     mutes: Zuk mututukoak
     storage: Multimedia biltegiratzea
+  filters:
+    contexts:
+      home: Hasierako denbora-lerroa
+      notifications: Jakinarazpenak
+      public: Denbora-lerro publikoak
+      thread: Elkarrizketak
+    edit:
+      title: Editatu iragazkia
+    errors:
+      invalid_context: Testuinguru baliogabe edo hutsa eman da
+      invalid_irreversible: Behin betiko iragazketa hasiera edo jakinarazpenen testuinguruan besterik ez dabil
+    index:
+      delete: Ezabatu
+      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.
@@ -486,9 +589,13 @@ eu:
     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:
     changes_saved_msg: Aldaketak ongi gorde dira!
-    powered_by: "(e)k %{link} darabil"
+    copy: Kopiatu
     save_changes: Gorde aldaketak
     validation_errors:
       one: Zerbait ez dabil ongi! Egiaztatu beheko errorea mesedez
@@ -524,8 +631,6 @@ eu:
       expires_at: Iraungitzea
       uses: Erabilerak
     title: Gonbidatu jendea
-  landing_strip_html: "<strong>%{name}</strong> %{link_to_root_path} instantziako erabiltzailea da. Fedibertsoko edozein tokitan kontua baduzu jarraitu dezakezu eta harremanetan jarri."
-  landing_strip_signup_html: Ez baduzu, <a href="%{sign_up_path}">hemen izena eman</a> dezakezu.
   lists:
     errors:
       limit: Gehieneko zerrenda kopurura heldu zara
@@ -599,6 +704,7 @@ eu:
   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:'
   remote_unfollow:
@@ -684,6 +790,7 @@ eu:
       private: Ezin dira publikoak ez diren toot-ak finkatu
       reblog: Bultzada bat ezin da finkatu
     show_more: Erakutsi gehiago
+    sign_in_to_participate: Eman izena elkarrizketan parte hartzeko
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Jarraitzaileak besterik ez
@@ -693,10 +800,9 @@ eu:
       unlisted: Zerrendatu gabea
       unlisted_long: Edonork ikusi dezake, baina ez da denbora-lerro publikoetan agertzen
   stream_entries:
-    click_to_show: Klik erakusteko
     pinned: Finkatutako toot-a
     reblogged: "(r)en bultzada"
-    sensitive_content: Eduki hunkigarria
+    sensitive_content: 'Kontuz: Eduki hunkigarria'
   terms:
     body_html: |
       <h2>Pribatutasun politika</h2>
@@ -787,6 +893,7 @@ eu:
   time:
     formats:
       default: "%Y(e)ko %b %d, %H:%M"
+      month: "%b %Y"
   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."
@@ -808,6 +915,19 @@ eu:
       explanation: Zure Mastodon kontuaren babes-kopia osoa eskatu duzu. Deskargatzeko prest dago!
       subject: Zure artxiboa deskargatzeko prest dago
       title: Artxiboa jasotzea
+    warning:
+      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.
+      review_server_policies: Berrikusi zerbitzariko politikak
+      subject:
+        disable: Zure  %{acct} kontua izoztu da
+        none: "%{acct} konturako abisua"
+        silence: Zure  %{acct} kontua murriztu da
+      title:
+        disable: Kontu izoztua
+        none: Abisua
+        silence: Kontu murriztua
     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.
@@ -819,7 +939,6 @@ eu:
       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
-      tip_bridge_html: Twitter-etik bazatoz, Mastodon-en lagunak aurkitu ditzakezu <a href="%{bridge_url}">zubi aplikazioa</a> erabiliz. Beraiek ere zubi aplikazioa erabili badute dabil besterik ez!
       tip_federated_timeline: Federatutako denbora-lerroan Mastodon sarearen trafikoa ikusten da. Baina zure instantziako auzokideak jarraitutakoak besterik ez daude hor, ez da osoa.
       tip_following: Lehenetsita zerbitzariko administratzailea jarraitzen duzu. Jende interesgarri gehiago aurkitzeko, egiaztatu denbora-lerro lokala eta federatua.
       tip_local_timeline: Denbora-lerro lokalean %{instance} instantziako trafikoa ikusten da. Hauek zure instantziako auzokideak dira!
@@ -827,8 +946,12 @@ eu:
       tips: Aholkuak
       title: Ongi etorri, %{name}!
   users:
+    follow_limit_reached: Ezin dituzu %{limit} pertsona baino gehiago jarraitu
     invalid_email: E-mail helbidea baliogabea da
     invalid_otp_token: Bi faktoreetako kode baliogabea
     otp_lost_help_html: 'Bietara sarbidea galdu baduzu, jarri kontaktuan hemen: %{email}'
     seamless_external_login: Kanpo zerbitzu baten bidez hasi duzu saioa, beraz pasahitza eta e-mail ezarpenak ez daude eskuragarri.
     signed_in_as: 'Saioa honela hasita:'
+  verification:
+    explanation_html: 'Ezin duzu <strong>zure burua zure profileko metadatuen esteken jabe gisa egiaztatu</strong>. Horretarako, estekatutako webgunean zure Mastodon profilera daraman esteka bat egon behar du. Mastodonera daraman esteka horrek<strong>derrigorrez</strong> <code>rel="me"</code> artibutua izan behar du . Estekaren testuak ez du axola. Hona adibide bat:'
+    verification: Egiaztaketa
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index 89ed2bbfb1c6df9ef694023edb744a73d8517aa8..e7dd86025f288fdd4b358510ff7a37fb421eaac7 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -5,13 +5,13 @@ fa:
     about_mastodon_html: ماستدون (Mastodon) یک شبکهٔ اجتماعی است که بر اساس پروتکل‌های آزاد وب و نرم‌افزارهای آزاد و کدباز ساخته شده است. این شبکه مانند ایمیل غیرمتمرکز است.
     about_this: درباره
     administered_by: 'با مدیریت:'
+    api: رابط برنامه‌نویسی کاربردی
+    apps: اپ‌های موبایل
     closed_registrations: ثبت‌نام روی این سرور هم‌اینک فعال نیست. اما شما می‌توانید سرور دیگری بیابید و با حسابی که آن‌جا می‌سازید دقیقاً به همین شبکه دسترسی داشته باشید.
     contact: تماس
     contact_missing: تعیین نشده
     contact_unavailable: موجود نیست
-    description_headline: "%{domain} چیست؟"
-    domain_count_after: سرور دیگر
-    domain_count_before: متصل به
+    documentation: مستندات
     extended_description_html: |
       <h3>جای خوبی برای قانون‌ها</h3>
       <p>توضیحات تکمیلی نوشته نشده است.</p>
@@ -28,25 +28,40 @@ fa:
     hosted_on: ماستدون، میزبانی‌شده روی %{domain}
     learn_more: بیشتر بدانید
     other_instances: فهرست سرورها
+    privacy_policy: سیاست رازداری
     source_code: کدهای منبع
-    status_count_after: چیز نوشته‌اند
-    status_count_before: که جمعاً
-    user_count_after: کاربر
+    status_count_after:
+      one: چیز نوشته‌اند
+      other: چیز نوشته‌اند
+    status_count_before: که در کنار هم
+    terms: شرایط کاربری
+    user_count_after:
+      one: کاربر
+      other: کاربر
     user_count_before: دارای
     what_is_mastodon: ماستدون چیست؟
   accounts:
+    choices_html: 'انتخاب‌های %{name}:'
     follow: پی بگیرید
-    followers: پیگیران
+    followers:
+      one: پیگیر
+      other: پیگیر
     following: پی می‌گیرد
+    joined: کاربر از %{date}
+    link_verified_on: مالکیت این نشانی در تاریخ %{date} بررسی شد
     media: عکس و ویدیو
     moved_html: "%{name} حساب خود را به %{new_profile_link} منتقل کرده است:"
     network_hidden: این اطلاعات در دسترس نیست
     nothing_here: این‌جا چیزی نیست!
     people_followed_by: کسانی که %{name} پی می‌گیرد
     people_who_follow: کسانی که %{name} را پی می‌گیرند
-    posts: نوشته‌ها
+    pin_errors:
+      following: شما باید پیگیر کاربری باشید که می‌خواهید ثابت کنید
+    posts:
+      one: بوق
+      other: بوق
+    posts_tab_heading: بوق‌ها
     posts_with_replies: نوشته‌ها و پاسخ‌ها
-    remote_follow: پیگیری غیرمستقیم
     reserved_username: این نام کاربری در دسترس نیست
     roles:
       admin: مدیر
@@ -106,13 +121,10 @@ fa:
       moderation_notes: یادداشت مدیر
       most_recent_activity: آخرین فعالیت‌ها
       most_recent_ip: آخرین IP ها
+      no_limits_imposed: بدون محدودیت
       not_subscribed: عضو نیست
-      order:
-        alphabetic: الفبایی
-        most_recent: تازه‌ترین‌ها
-        title: ترتیب
       outbox_url: نشانی صندوق خروجی
-      perform_full_suspension: انجام تعلیق کامل
+      perform_full_suspension: تعلیق
       profile_url: نشانی نمایه
       promote: ترفیع‌دادن
       protocol: پروتکل
@@ -138,11 +150,12 @@ fa:
       shared_inbox_url: نشانی صندوق ورودی مشترک
       show:
         created_reports: گزارش‌ها از طرف این حساب
-        report: گزارش
         targeted_reports: گزارش‌ها دربارهٔ این حساب
       silence: بی‌صدا
+      silenced: بی‌صداشده
       statuses: نوشته‌ها
       subscribe: اشتراک
+      suspended: تعلیق‌شده
       title: حساب‌ها
       unconfirmed_email: ایمیل تأییدنشده
       undo_silenced: واگردانی بی‌صداکردن
@@ -159,6 +172,7 @@ fa:
         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} را پاک کرد"
@@ -180,6 +194,7 @@ fa:
         unsuspend_account: "%{name} حساب کاربر %{target} را از تعلیق خارج کرد"
         update_custom_emoji: "%{name} شکلک %{target} را به‌روز کرد"
         update_status: "%{name} نوشتهٔ %{target} را به‌روز کرد"
+      deleted_status: "(بوق پاک‌شده)"
       title: سیاههٔ بازرسی
     custom_emojis:
       by_domain: دامین
@@ -206,6 +221,27 @@ fa:
       update_failed_msg: این شکلک نتوانست به‌روز شود
       updated_msg: شکلک با موفقیت به‌روز شد!
       upload: بارگذاری
+    dashboard:
+      backlog: کارهای باقیمانده
+      config: پیکربندی
+      feature_deletions: حساب‌های حذف‌شده
+      feature_invites: دعوت‌نامه‌ها
+      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: مسدودکردن دامین در حال انجام است
@@ -222,11 +258,8 @@ fa:
         title: مسدودسازی دامین دیگر
       reject_media: نپذیرفتن پرونده‌های تصویری
       reject_media_hint: تصویرهای ذخیره‌شده در این‌جا را پاک می‌کند و جلوی دریافت تصویرها را در آینده می‌گیرد. بی‌تأثیر برای معلق‌شده‌ها
-      severities:
-        noop: هیچ
-        silence: بی‌صداکردن
-        suspend: معلق‌کردن
-      severity: شدت
+      reject_reports: نپذیرفتن گزارش‌ها
+      reject_reports_hint: گزارش‌هایی را که از این دامین می‌آید نادیده می‌گیرد. بی‌تأثیر برای معلق‌شده‌ها
       show:
         affected_accounts:
           one: روی یک حساب در پایگاه داده تأثیر گذاشت
@@ -236,7 +269,6 @@ fa:
           suspend: معلق‌شدن همهٔ حساب‌های این دامین را لغو کن
         title: واگردانی مسدودسازی دامنه برای %{domain}
         undo: واگردانی
-      title: دامین‌های مسدودشده
       undo: واگردانی
     email_domain_blocks:
       add_new: افزودن تازه
@@ -249,18 +281,30 @@ fa:
         title: مسدودسازی دامین ایمیل تازه
       title: مسدودسازی دامین‌های ایمیل
     instances:
-      account_count: حساب‌های شناخته‌شده
-      domain_name: دامین
-      reset: بازنشانی
-      search: جستجو
       title: سرورهای شناخته‌شده
     invites:
+      deactivate_all: غیرفعال‌کردن همه
       filter:
         all: همه
         available: در دسترس
         expired: منقضی‌شده
         title: فیلتر
       title: دعوت‌ها
+    relays:
+      add_new: افزودن رلهٔ تازه
+      delete: حذف
+      description_html: یک <strong>رلهٔ میان‌سروری</strong> (federation relay) یک سرور میانجی است که حجم زیادی از بوق‌های عمومی را بین سرورهای گوناگونی که عضوش می‌شوند جابه‌جا می‌کند. <strong>رله‌ها به سرورهای کوچک و متوسط کمک می‌کنند تا مطالب عمومی بیشتری را بیابند.</strong> اگر رله نباشد، این مطالب عمومی تنها وقتی پیدا می‌شوند که کاربران محلی خودشان پیگیر کاربران روی سرورهای دیگر شوند.
+      disable: غیرفعال‌کردن
+      disabled: غیرفعال
+      enable: فعال‌سازی
+      enable_hint: اگر فعال باشد، سرور شما عضو همهٔ بوق‌های عمومی‌ای را که از این رله می‌آید می‌گیرد، و بوق‌های عمومی این سرور را به آن می‌فرستند.
+      enabled: فعال
+      inbox_url: نشانی رله
+      pending: در انتظار پذیرش رله
+      save_and_enable: ذخیره و فعال‌سازی
+      setup: پیوستن به رله‌ها
+      status: وضعیت
+      title: رله‌ها
     report_notes:
       created_msg: یادداشت گزارش با موفقیت ساخته شد!
       destroyed_msg: یادداشت گزارش با موفقیت حذف شد!
@@ -275,7 +319,6 @@ fa:
       comment:
         none: خالی
       created_at: گزارش‌شده
-      id: شناسه
       mark_as_resolved: علامت‌گذاری به عنوان حل‌شده
       mark_as_unresolved: علامت‌گذاری به عنوان حل‌نشده
       notes:
@@ -286,20 +329,15 @@ fa:
         placeholder: کارهایی را که در این باره انجام شده، یا هر به‌روزرسانی دیگری را بنویسید...
       reopen: دوباره به جریان بیندازید
       report: 'گزارش #%{id}'
-      report_contents: محتوا
       reported_account: حساب گزارش‌شده
       reported_by: گزارش از طرف
       resolved: حل‌شده
       resolved_msg: گزارش با موفقیت حل شد!
-      silence_account: بی‌صدا کردن حساب
       status: نوشته
-      suspend_account: معلق‌کردن حساب
-      target: هدف
       title: گزارش‌ها
       unassign: پس‌گرفتن مسئولیت
       unresolved: حل‌نشده
       updated_at: به‌روز شد
-      view: نمایش
     settings:
       activity_api_enabled:
         desc_html: تعداد بوق‌های محلی، کاربران فعال، و کاربران تازه در هر هفته
@@ -310,9 +348,15 @@ fa:
       contact_information:
         email: ایمیل کاری
         username: نام کاربری
+      custom_css:
+        desc_html: ظاهر ماستدون را با CSS-ای که در همهٔ صفحه‌ها جاسازی می‌شود تغییر دهید
+        title: سبک CSS سفارشی
       hero:
         desc_html: در صفحهٔ آغازین نمایش می‌یابد. دست‌کم ۶۰۰×۱۰۰ پیکسل توصیه می‌شود. اگر تعیین نشود، با تصویر بندانگشتی سرور جایگزین خواهد شد
         title: تصویر سربرگ
+      mascot:
+        desc_html: در صفحه‌های گوناگونی نمایش می‌یابد. دست‌کم ۲۹۳×۲۰۵ پیکسل. اگر تعیین نشود، با تصویر پیش‌فرض جایگزین خواهد شد
+        title: تصویر نماد
       peers_api_enabled:
         desc_html: دامین‌هایی که این سرور به آن‌ها برخورده است
         title: انتشار فهرست سرورهای یافته‌شده
@@ -339,11 +383,14 @@ fa:
         desc_html: نمایش علامت همکار روی صفحهٔ کاربر
         title: نمایش علامت همکار
       site_description:
-        desc_html: معرفی کوتاهی که روی صفحهٔ اصلی و همچنین به عنوان فرادادهٔ صفحه‌ها نمایش می‌یابد. می‌توانید HTML بنویسید, به‌ویژه <code>&lt;a&gt;</code> و <code>&lt;em&gt;</code>.
+        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: توضیح کوتاه دربارهٔ سایت
       site_terms:
         desc_html: می‌توانید سیاست رازداری، شرایط استفاده، یا سایر مسائل قانونی را به دلخواه خود بنویسید. تگ‌های HTML هم مجاز است
         title: شرایط استفادهٔ سفارشی
@@ -365,6 +412,7 @@ fa:
       media:
         title: رسانه
       no_media: بدون عکس یا ویدیو
+      no_status_selected: هیچ بوقی تغییری نکرد زیرا هیچ‌کدام از آن‌ها انتخاب نشده بودند
       title: نوشته‌های حساب
       with_media: دارای عکس یا ویدیو
     subscriptions:
@@ -396,7 +444,7 @@ fa:
     warning: خیلی مواظب این اطلاعات باشید و آن را به هیچ کس ندهید!
     your_token: کد دسترسی شما
   auth:
-    agreement_html: پیش از عضو شدن باید <a href="%{rules_path}">قوانین این سرور</a> و <a href="%{terms_path}">شرایط استفادهٔ</a> ما را بپذیرید.
+    agreement_html: با کلیک روی دکمهٔ عضو شدن، شما <a href="%{rules_path}">قوانین این سرور</a> و <a href="%{terms_path}">شرایط استفادهٔ</a> ما را می‌پذیرید.
     change_password: رمز
     confirm_email: تأیید ایمیل
     delete_account: پاک‌کردن حساب
@@ -463,7 +511,7 @@ fa:
     '500':
       content: شرمنده، یک چیزی از سمت ما اشتباه شده.
       title: این صفحه درست نیست
-    noscript_html: برای استفاده از نسخهٔ تحت وب ماستدون، لطفاً جاوااسکریپت را فعال کنید. یا به جایش می‌توانید <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">یک اپ ماستدون</a> را به‌کار ببرید.
+    noscript_html: برای استفاده از نسخهٔ تحت وب ماستدون، لطفاً جاوااسکریپت را فعال کنید. یا به جایش می‌توانید <a href="%{apps_path}">یک اپ ماستدون</a> را به‌کار ببرید.
   exports:
     archive_takeout:
       date: تاریخ
@@ -505,9 +553,13 @@ fa:
     true_privacy_html: لطفاً بدانید که <strong>داشتن حریم خصوصی واقعی تنها با رمزگذاری سرتاسر (end-to-end encryption) ممکن است</strong>.
     unlocked_warning_html: هر کسی می‌تواند پیگیر شما شود تا بلافاصله نوشته‌های خصوصی شما را ببیند. اگر  %{lock_link} خواهید توانست درخواست‌های پیگیری را بررسی کرده و نپذیرید.
     unlocked_warning_title: حساب شما خصوصی نیست
+  footer:
+    developers: برنامه‌نویسان
+    more: بیشتر…
+    resources: منابع
   generic:
     changes_saved_msg: تغییرات با موفقیت ذخیره شدند!
-    powered_by: نیرو گرفته از %{link}
+    copy: رونوشت
     save_changes: ذخیرهٔ تغییرات
     validation_errors:
       one: یک چیزی هنوز درست نیست! لطفاً خطاهای زیر را ببینید
@@ -543,8 +595,6 @@ fa:
       expires_at: تاریخ انقضا
       uses: استفاده‌ها
     title: دعوت دیگران
-  landing_strip_html: "<strong>%{name}</strong> کاربری روی %{link_to_root_path} است. شما با داشتن حساب روی هر سروری می‌توانید نوشته‌های او را پیگیری کرده یا با او ارتباط داشته باشید."
-  landing_strip_signup_html: اگر هنوز حسابی ندارید <a href="%{sign_up_path}">این‌جا حساب باز کنید</a>.
   lists:
     errors:
       limit: از این بیشتر نمی‌شود فهرست داشت
@@ -704,6 +754,7 @@ fa:
       private: نوشته‌های غیرعمومی را نمی‌توان ثابت کرد
       reblog: بازبوق‌ها را نمی‌توان ثابت کرد
     show_more: نمایش
+    sign_in_to_participate: برای شرکت در گفتگو وارد حساب خود شوید
     title: '%{name}: "%{quote}"'
     visibilities:
       private: خصوصی
@@ -713,7 +764,6 @@ fa:
       unlisted: فهرست‌نشده
       unlisted_long: عمومی، ولی در فهرست نوشته‌ها نمایش نمی‌یابد
   stream_entries:
-    click_to_show: برای نمایش کلیک کنید
     pinned: نوشته‌های ثابت
     reblogged: بازبوقید
     sensitive_content: محتوای حساس
@@ -726,6 +776,7 @@ fa:
   time:
     formats:
       default: "%d %b %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: برای تأیید، کدی را که برنامهٔ تأییدکننده ساخته است وارد کنید
     description_html: اگر <strong>ورود دومرحله‌ای</strong> را فعال کنید، برای ورود به سیستم به تلفن خود نیاز خواهید داشت تا برایتان یک کد موقتی بسازد.
@@ -758,7 +809,6 @@ fa:
       review_preferences_action: تغییر ترجیحات
       review_preferences_step: با رفتن به صفحهٔ ترجیحات می‌توانید چیزهای گوناگونی را تنظیم کنید. مثلاً این که چه ایمیل‌های آگاه‌سازی‌ای به شما فرستاده شود، یا حریم خصوصی پیش‌فرض نوشته‌هایتان چه باشد. اگر بیماری سفر (حالت تهوع بر اثر دیدن اجسام متحرک) ندارید، می‌توانید پخش خودکار ویدیوها را فعال کنید.
       subject: به ماستدون خوش آمدید
-      tip_bridge_html: اگر پیش از این کاربر توییتر بودید، می‌توانید دوستان توییتری خود را که در ماستدون هستند به کمک <a href="%{bridge_url}">bridge app</a> پیدا کنید. البته این فقط وقتی کار می‌کند که آن‌ها هم این اپ را به کار برده باشند!
       tip_federated_timeline: "«فهرست نوشته‌های همه‌جا» نمایی از کل شبکهٔ بزرگ ماستدون به شما می‌دهد. البته این فهرست فقط افردای را نشان می‌دهد که هم‌سروری‌های شما آن‌ها را پیگیری می‌کنند، و بنابراین ممکن است کامل نباشد."
       tip_following: شما به طور پیش‌فرض مدیر(های) سرور خود را پی می‌گیرید. برای یافتن افراد جالب دیگر، فهرست «نوشته‌های محلی» و «نوشته‌های همه‌جا» را ببینید.
       tip_local_timeline: فهرست نوشته‌های محلی نمایی کلی از کاربران روی %{instance} را ارائه می‌دهد. این‌ها همسایه‌های شما هستند!
@@ -766,8 +816,12 @@ fa:
       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> برای این کار، صفحه‌ای که به آن پیوند داده‌اید، خودش باید پیوندی به نمایهٔ ماستدون شما داشته باشد. پیوند در آن صفحه <strong>باید</strong> عبارت <code>rel="me"‎</code> را به عنوان attribute در خود داشته باشد. محتوای متن پیوند اهمتی ندارد. یک نمونه از چنین پیوندی:'
+    verification: تأیید
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index df4863809144109d8bd013855ff9e314b77f5b4b..4b5635622877f3d91c8ef77fbcad8b607b0de2fd 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -9,9 +9,6 @@ fi:
     contact: Ota yhteyttä
     contact_missing: Ei asetettu
     contact_unavailable: Ei saatavilla
-    description_headline: Mikä on %{domain}?
-    domain_count_after: muuhun instanssiin
-    domain_count_before: Yhdistyneenä
     extended_description_html: |
       <h3>Hyvä paikka säännöille</h3>
       <p>Pidempää kuvausta ei ole vielä laadittu.</p>
@@ -46,7 +43,6 @@ fi:
     people_who_follow: Käyttäjän %{name} seuraajat
     posts: Tuuttaukset
     posts_with_replies: Tuuttaukset ja vastaukset
-    remote_follow: Etäseuranta
     reserved_username: Käyttäjänimi on varattu
     roles:
       admin: Ylläpitäjä
@@ -106,10 +102,6 @@ fi:
       most_recent_activity: Viimeisin toiminta
       most_recent_ip: Viimeisin IP
       not_subscribed: Ei tilaaja
-      order:
-        alphabetic: Aakkosjärjestys
-        most_recent: Uusin
-        title: Järjestys
       outbox_url: Lähtevän postilaatikon osoite
       perform_full_suspension: Siirrä kokonaan jäähylle
       profile_url: Profiilin osoite
@@ -137,7 +129,6 @@ fi:
       shared_inbox_url: Jaetun saapuvan postilaatikon osoite
       show:
         created_reports: Tämän tilin luomat raportit
-        report: raportti
         targeted_reports: Tästä tilistä tehdyt raportit
       silence: Hiljennä
       statuses: Tilat
@@ -220,11 +211,6 @@ fi:
         title: Uusi verkkotunnuksen esto
       reject_media: Hylkää mediatiedostot
       reject_media_hint: Poistaa paikallisesti tallennetut mediatiedostot eikä lataa niitä enää jatkossa. Ei merkitystä jäähyn kohdalla
-      severities:
-        noop: Ei mitään
-        silence: Hiljennys
-        suspend: Jäähy
-      severity: Vakavuus
       show:
         affected_accounts:
           one: Vaikuttaa yhteen tiliin tietokannassa
@@ -234,7 +220,6 @@ fi:
           suspend: Peru kaikkien tässä verkkotunnuksessa jo olemassa olevien tilien jäähy
         title: Peru verkkotunnuksen %{domain} esto
         undo: Peru
-      title: Verkkotunnusten estot
       undo: Peru
     email_domain_blocks:
       add_new: Lisää uusi
@@ -247,10 +232,6 @@ fi:
         title: Uusi sähköpostiestolistan merkintä
       title: Sähköpostiestolista
     instances:
-      account_count: Tiedossa olevat tilit
-      domain_name: Verkkotunnus
-      reset: Palauta
-      search: Hae
       title: Tiedossa olevat instanssit
     invites:
       filter:
@@ -272,7 +253,6 @@ fi:
       comment:
         none: Ei mitään
       created_at: Raportoitu
-      id: Tunniste
       mark_as_resolved: Merkitse ratkaistuksi
       mark_as_unresolved: Merkitse ratkaisemattomaksi
       notes:
@@ -283,19 +263,14 @@ fi:
         placeholder: Kuvaile mitä toimia on tehty tai muita päivityksiä tähän raporttiin…
       reopen: Avaa raportti uudestaan
       report: Raportti nro %{id}
-      report_contents: Sisältö
       reported_account: Raportoitu tili
       reported_by: Raportoija
       resolved: Ratkaistut
       resolved_msg: Raportti onnistuneesti ratkaistu!
-      silence_account: Hiljennä tili
       status: Tila
-      suspend_account: Siirrä tili jäähylle
-      target: Kohde
       title: Raportit
       unresolved: Ratkaisemattomat
       updated_at: Päivitetty
-      view: Näytä
     settings:
       activity_api_enabled:
         desc_html: Paikallisesti julkaistujen tilojen, aktiivisten käyttäjien ja uusien rekisteröintien määrät viikoittain
@@ -456,7 +431,7 @@ fi:
     '500':
       content: Valitettavasti jokin meni pieleen meidän päässämme.
       title: Sivu ei ole oikein
-    noscript_html: Mastodon-selainsovelluksen käyttöön vaaditaan JavaScript. Voit vaihtoehtoisesti kokeilla jotakin omalle käyttöjärjestelmällesi tehtyä Mastodon<a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">sovellusta</a>.
+    noscript_html: Mastodon-selainsovelluksen käyttöön vaaditaan JavaScript. Voit vaihtoehtoisesti kokeilla jotakin omalle käyttöjärjestelmällesi tehtyä Mastodon<a href="%{apps_path}">sovellusta</a>.
   exports:
     archive_takeout:
       date: Päiväys
@@ -484,7 +459,6 @@ fi:
     unlocked_warning_title: Tiliäsi ei ole lukittu
   generic:
     changes_saved_msg: Muutosten tallennus onnistui!
-    powered_by: voimanlähteenä %{link}
     save_changes: Tallenna muutokset
     validation_errors:
       one: Kaikki ei ole aivan oikein! Tarkasta alla oleva virhe
@@ -519,8 +493,6 @@ fi:
       expires_at: Vanhenee
       uses: Käytetty
     title: Kutsu ihmisiä
-  landing_strip_html: "<strong>%{name}</strong> on käyttäjänä palvelimella %{link_to_root_path}. Voit seurata heitä tai pitää heihin yhteyttä, jos sinulla on tili missä tahansa fediversumin kolkassa."
-  landing_strip_signup_html: Jos sinulla ei ole tiliä, voit <a href="%{sign_up_path}">rekisteröityä tätä kautta</a>.
   lists:
     errors:
       limit: Sinulla on jo suurin sallittu määrä listoja
@@ -620,7 +592,7 @@ fi:
       uc_browser: UCBrowser
       weibo: Weibo
     current_session: Nykyinen istunto
-    description: "%{selain}, %{platform}"
+    description: "%{browser}, %{platform}"
     explanation: Nämä verkkoselaimet ovat tällä hetkellä kirjautuneet Mastodon-tilillesi.
     ip: IP
     platforms:
@@ -684,7 +656,6 @@ fi:
       unlisted: Listaamaton julkinen
       unlisted_long: Kaikki voivat nähdä, mutta ei näytetä julkisilla aikajanoilla
   stream_entries:
-    click_to_show: Katso napsauttamalla
     pinned: Kiinnitetty tuuttaus
     reblogged: buustasi
     sensitive_content: Arkaluontoista sisältöä
@@ -721,19 +692,18 @@ fi:
       edit_profile_step: Voit mukauttaa profiiliasi lataamalla profiilikuvan ja otsakekuvan, muuttamalla näyttönimeäsi ym. Jos haluat hyväksyä uudet seuraajat ennen kuin he voivat seurata sinua, voit lukita tilisi.
       explanation: Näillä vinkeillä pääset alkuun
       final_action: Ala julkaista
-      final_step: 'Ala julkaista! Vaikkei sinulla olisi seuraajia, monet voivat nähdä julkiset viestisi esimerkiksi paikallisella aikajanalla ja hashtagien avulla. Kannattaa esittäytyä! Käytä hashtagia #introductions. (Jos haluat esittäytyä myös suomeksi, se kannattaa tehdä erillisessä tuuttauksessa ja käyttää hashtagia #esittely.)'
+      final_step: 'Ala julkaista! Vaikkei sinulla olisi seuraajia, monet voivat nähdä julkiset viestisi esimerkiksi paikallisella aikajanalla ja hashtagien avulla. Kannattaa esittäytyä! Käytä hashtagia #introductions. (Jos haluat esittäytyä myös suomeksi, se kannattaa tehdä erillisessä tuuttauksessa ja käyttää hashtagia #esittely.).'
       full_handle: Koko käyttäjätunnuksesi
       full_handle_hint: Kerro tämä ystävillesi, niin he voivat lähettää sinulle viestejä tai löytää sinut toisen instanssin kautta.
       review_preferences_action: Muuta asetuksia
       review_preferences_step: Käy tarkistamassa, että asetukset ovat haluamallasi tavalla. Voit valita, missä tilanteissa haluat saada sähköpostia, mikä on julkaisujesi oletusnäkyvyys jne. Jos et saa helposti pahoinvointia, voit valita, että GIF-animaatiot toistetaan automaattisesti.
       subject: Tervetuloa Mastodoniin
-      tip_bridge_html: Jos tulet Twitteristä, voit etsiä ystäviäsi Mastodonista <a href="%{bridge_url}">siltasovelluksen</a> avulla. Se kuitenkin löytää heidät vain, jos hekin käyttävät sitä!
       tip_federated_timeline: Yleinen aikajana näyttää sisältöä koko Mastodon-verkostosta. Siinä näkyvät kuitenkin vain ne henkilöt, joita oman instanssisi käyttäjät seuraavat. Siinä ei siis näytetä aivan kaikkea.
       tip_following: Oletusarvoisesti seuraat oman palvelimesi ylläpitäjiä. Etsi lisää kiinnostavia ihmisiä paikalliselta ja yleiseltä aikajanalta.
       tip_local_timeline: Paikallinen aikajana näyttää instanssin %{instance} käyttäjien julkaisut. He ovat naapureitasi!
       tip_mobile_webapp: Jos voit lisätä Mastodonin mobiiliselaimen kautta aloitusnäytöllesi, voit vastaanottaa push-ilmoituksia. Toiminta vastaa monin tavoin tavanomaista sovellusta!
       tips: Vinkkejä
-      title: Tervetuloa mukaan, %name}!
+      title: Tervetuloa mukaan, %{name}!
   users:
     invalid_email: Virheellinen sähköpostiosoite
     invalid_otp_token: Virheellinen kaksivaiheisen todentamisen koodi
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 1e1471f7295a14deeaf79ea3bfb142df840ff4bc..cbff58d918085e62404dffb2860deeac018bc3de 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -4,23 +4,23 @@ 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
-    administered_by: 'Administré par :'
+    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.
     contact: Contact
     contact_missing: Manquant
     contact_unavailable: Non disponible
-    description_headline: Qu’est-ce que %{domain} ?
-    domain_count_after: autres instances
-    domain_count_before: Connecté⋅e⋅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’environnement fermés. Il n’y existe aucune autorité centrale.
+      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 dispostion, une grande granularité en terme de diffusion et la possibilité de masquer vos messages derrières des avertissements, vous êtes libre de vous exprimer de la manière qui vous plaît.
+      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
@@ -28,25 +28,41 @@ fr:
     hosted_on: Instance Mastodon hébergée par %{domain}
     learn_more: En savoir plus
     other_instances: Liste des instances
+    privacy_policy: Politique de vie privée
     source_code: Code source
-    status_count_after: statuts
+    status_count_after:
+      one: Statut
+      other: Statuts
     status_count_before: Ayant publié
-    user_count_after: utilisateurâ‹…iceâ‹…s
+    terms: Conditions d'utilisation
+    user_count_after:
+      one: utilisateur
+      other: utilisateurs
     user_count_before: Abrite
     what_is_mastodon: Qu’est-ce que Mastodon ?
   accounts:
+    choices_html: "%{name} recommande :"
     follow: Suivre
-    followers: Abonné⋅e⋅s
+    followers:
+      one: Abonné·e
+      other: Abonné⋅e⋅s
     following: Abonnements
+    joined: Inscrit·e en %{date}
+    last_active: actif dernièrement
+    link_verified_on: La propriété de ce lien a été vérifiée le %{date}
     media: Médias
-    moved_html: "%{name} a changé de compte pour %{new_profile_link} :"
-    network_hidden: Cette information n'est pas disponible
+    moved_html: "%{name} a changé de compte pour %{new_profile_link} :"
+    network_hidden: Cette information n’est pas disponible
     nothing_here: Rien à voir ici !
     people_followed_by: Personnes suivies par %{name}
     people_who_follow: Personnes qui suivent %{name}
-    posts: Statuts
+    pin_errors:
+      following: Vous devez être déjà abonné·e à la personne que vous désirez recommander
+    posts:
+      one: Pouet
+      other: Pouets
+    posts_tab_heading: Pouets
     posts_with_replies: Statuts & réponses
-    remote_follow: Suivre à distance
     reserved_username: Ce nom d’utilisateur⋅ice est réservé
     roles:
       admin: Admin
@@ -54,6 +70,9 @@ fr:
       moderator: Modérateur·trice
     unfollow: Ne plus suivre
   admin:
+    account_actions:
+      action: Effectuer une action
+      title: Effectuer une action de modération sur %{acct}
     account_moderation_notes:
       create: Laisser un commentaire
       created_msg: Note de modération créée avec succès !
@@ -64,7 +83,7 @@ fr:
       avatar: Avatar
       by_domain: Domaine
       change_email:
-        changed_msg: Courriel du compte modifié avec succès !
+        changed_msg: Courriel du compte modifié avec succès !
         current_email: Courriel actuel
         label: Modifier le courriel
         new_email: Nouveau courriel
@@ -73,6 +92,7 @@ fr:
       confirm: Confirmer
       confirmed: Confirmé
       confirming: Confirmation
+      deleted: Effacé
       demote: Rétrograder
       disable: Désactiver
       disable_two_factor_authentication: Désactiver l’authentification à deux facteurs
@@ -88,7 +108,9 @@ fr:
       followers: Abonné⋅e⋅s
       followers_url: URL des abonné·e·s
       follows: Abonnements
+      header: Entête
       inbox_url: URL d’entrée
+      invited_by: Invité par
       ip: Adresse IP
       location:
         all: Tous
@@ -99,6 +121,7 @@ fr:
       media_attachments: Fichiers médias
       memorialize: Convertir en mémorial
       moderation:
+        active: Actif
         all: Tous
         silenced: Masqués
         suspended: Suspendus
@@ -106,24 +129,22 @@ fr:
       moderation_notes: Notes de modération
       most_recent_activity: Dernière activité
       most_recent_ip: Adresse IP la plus récente
+      no_limits_imposed: Aucune limite imposée
       not_subscribed: Non abonné
-      order:
-        alphabetic: Alphabétique
-        most_recent: Plus récent
-        title: Tri
       outbox_url: URL de sortie
-      perform_full_suspension: Effectuer une suspension complète
+      perform_full_suspension: Suspendre
       profile_url: URL du profil
       promote: Promouvoir
       protocol: Protocole
       public: Publique
       push_subscription_expires: Expiration de l’abonnement PuSH
-      redownload: Rafraîchir les avatars
-      remove_avatar: Supprimer l'avatar
+      redownload: Rafraîchir le profil
+      remove_avatar: Supprimer l’avatar
+      remove_header: Supprimer l'entête
       resend_confirmation:
-        already_confirmed: Cet utilisateur est déjà confirmé
+        already_confirmed: Cet·te utilisateur·ice est déjà confirmé·e
         send: Renvoyer un courriel de confirmation
-        success: Email de confirmation envoyé avec succès !
+        success: Courriel de confirmation envoyé avec succès !
       reset: Réinitialiser
       reset_password: Réinitialiser le mot de passe
       resubscribe: Se réabonner
@@ -137,12 +158,13 @@ fr:
       search: Rechercher
       shared_inbox_url: URL de la boite de réception partagée
       show:
-        created_reports: Signalements créés par ce compte
-        report: signalement
-        targeted_reports: Signalements créés visant ce compte
+        created_reports: Signalements faits
+        targeted_reports: Signalés par d'autres
       silence: Masquer
+      silenced: Silencié
       statuses: Statuts
       subscribe: S’abonner
+      suspended: Suspendu
       title: Comptes
       unconfirmed_email: Courriel non-confirmé
       undo_silenced: Démasquer
@@ -152,35 +174,38 @@ fr:
       web: Web
     action_logs:
       actions:
-        assigned_to_self_report: "%{name} s'est assigné le signalement de %{target} à eux-même"
-        change_email_user: "%{name} a modifié l'adresse de courriel de l'utilisateur %{target}"
-        confirm_user: "%{name} adresse courriel confirmée de l'utilisateur %{target}"
-        create_custom_emoji: "%{name} a importé de nouveaux emoji %{target}"
+        assigned_to_self_report: "%{name} s’est assigné·e le signalement de %{target}"
+        change_email_user: "%{name} a modifié l’adresse de courriel de l’utilisateur·rice %{target}"
+        confirm_user: "%{name} adresse courriel confirmée de l’utilisateur·ice %{target}"
+        create_account_warning: "%{name} a envoyé une attention à %{target}"
+        create_custom_emoji: "%{name} a importé de nouveaux émojis %{target}"
         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 %{target}"
+        demote_user: "%{name} a rétrogradé l’utilisateur·ice %{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}"
-        disable_2fa_user: "%{name} a désactivé l'authentification à deux facteurs pour l'utilisateur %{target}"
-        disable_custom_emoji: "%{name} a désactivé l'emoji %{target}"
-        disable_user: "%{name} a désactivé le login pour l'utilisateur %{target}"
-        enable_custom_emoji: "%{name} a activé l'emoji %{target}"
-        enable_user: "%{name} a activé le login pour l'utilisateur %{target}"
+        disable_2fa_user: "%{name} a désactivé l’authentification à deux facteurs pour l’utilisateur·ice %{target}"
+        disable_custom_emoji: "%{name} a désactivé l’émoji %{target}"
+        disable_user: "%{name} a désactivé le login pour l’utilisateur·ice %{target}"
+        enable_custom_emoji: "%{name} a activé l’émoji %{target}"
+        enable_user: "%{name} a activé le login pour l’utilisateur·ice %{target}"
         memorialize_account: "%{name} a transformé le compte de %{target} en une page de mémorial"
-        promote_user: "%{name} a promu l'utilisateur %{target}"
-        remove_avatar_user: "%{name} a supprimé l'avatar de %{target}'s"
-        reopen_report: "%{name} a ré-ouvert le signalement %{target}"
+        promote_user: "%{name} a promu l’utilisateur·ice %{target}"
+        remove_avatar_user: "%{name} a supprimé l’avatar de %{target}"
+        reopen_report: "%{name} a rouvert le signalement %{target}"
         reset_password_user: "%{name} a réinitialisé le mot de passe de %{target}"
-        resolve_report: "%{name} a résolu la dénonciation de %{target}"
+        resolve_report: "%{name} a résolu le signalement %{target}"
         silence_account: "%{name} a mis le compte %{target} en mode silence"
         suspend_account: "%{name} a suspendu le compte %{target}"
-        unassigned_report: "%{name} a dés-assigné le signalement %{target}"
+        unassigned_report: "%{name} a désassigné le signalement %{target}"
         unsilence_account: "%{name} a mis fin au mode silence de %{target}"
         unsuspend_account: "%{name} a réactivé le compte de %{target}"
-        update_custom_emoji: "%{name} a mis à jour l'emoji %{target}"
+        update_custom_emoji: "%{name} a mis à jour l’émoji %{target}"
         update_status: "%{name} a mis à jour le statut de %{target}"
-      title: Journal d'audit
+      deleted_status: "(statut supprimé)"
+      title: Journal d’audit
     custom_emojis:
       by_domain: Domaine
       copied_msg: Copie locale de l’émoji créée avec succès !
@@ -201,13 +226,35 @@ fr:
       overwrite: Réécrire
       shortcode: Raccourci
       shortcode_hint: Au moins deux caractères, seulement des caractères alphanumériques ou des tirets bas
-      title: Émoji personnalisés
+      title: Émojis personnalisés
       unlisted: Délisté
-      update_failed_msg: N'a pas pu mettre à jour cet emoji
-      updated_msg: Emoji mis à jour avec succès !
+      update_failed_msg: N’a pas pu mettre à jour cet émoji
+      updated_msg: Émoji mis à jour avec succès !
       upload: Téléverser
+    dashboard:
+      backlog: tâches en attente
+      config: Configuration
+      feature_deletions: Suppressions de comptes
+      feature_invites: Liens d’invitation
+      feature_profile_directory: Annuaire des profils
+      feature_registrations: Inscriptions
+      feature_relay: Relais de fédération
+      features: Fonctionnalités
+      hidden_service: Fédération avec des services cachés
+      open_reports: signalements non résolus
+      recent_users: Utilisateur·rice·s récent·e·s
+      search: Recherche plein texte
+      single_user_mode: Mode utilisateur·ice unique
+      software: Logiciel
+      space: Espace utilisé
+      title: Tableau de bord
+      total_users: utilisateur·rice·s au total
+      trends: Tendances
+      week_interactions: interactions cette semaine
+      week_users_active: actif·ve·s cette semaine
+      week_users_new: utilisateur·rice·s cette semaine
     domain_blocks:
-      add_new: Ajouter
+      add_new: Ajouter un nouveau bloqueur de domaine
       created_msg: Le blocage de domaine est désormais activé
       destroyed_msg: Le blocage de domaine a été désactivé
       domain: Domaine
@@ -222,11 +269,13 @@ fr:
         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
-      severities:
-        noop: Aucune
-        silence: Masquer
-        suspend: Suspendre
-      severity: Séverité
+      reject_reports: Rapports de rejet
+      reject_reports_hint: Ignorez tous les rapports provenant de ce domaine. Sans objet pour les suspensions
+      rejecting_media: rejet des fichiers multimédia
+      rejecting_reports: rejet de rapports
+      severity:
+        silence: silencié
+        suspend: suspendu
       show:
         affected_accounts:
           one: Un compte affecté dans la base de données
@@ -236,8 +285,7 @@ fr:
           suspend: Annuler la suspension sur tous les comptes existants pour ce domaine
         title: Annuler le blocage de domaine pour %{domain}
         undo: Annuler
-      title: Blocage de domaines
-      undo: Annuler
+      undo: Annuler le bloqueur de domaine
     email_domain_blocks:
       add_new: Ajouter
       created_msg: Le blocage de domaine de courriel est désormais activé
@@ -248,34 +296,60 @@ fr:
         create: Créer le blocage
         title: Nouveau blocage de domaine de courriel
       title: Blocage de domaines de courriel
+    followers:
+      back_to_account: Retour au compte
+      title: Abonné⋅e⋅s de %{acct}
     instances:
-      account_count: Comptes connus
-      domain_name: Domaine
-      reset: Réinitialiser
-      search: Rechercher
-      title: Instances connues
+      known_accounts:
+        one: "%{count} compte connu"
+        other: "%{count} comptes connus"
+      moderation:
+        all: Tout
+        limited: Limité
+        title: Modération
+      title: Fédération
+      total_blocked_by_us: Bloqués par nous
+      total_followed_by_them: Suivi par eux
+      total_followed_by_us: Suivi par nous
+      total_reported: Signalements à leurs propos
+      total_storage: Attachements de média
     invites:
+      deactivate_all: Tout désactiver
       filter:
         all: Tout
         available: Disponible
         expired: Expiré
         title: Filtre
       title: Invitations
+    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.
+      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
+      save_and_enable: Sauvegarder et activer
+      setup: Paramétrer une connexion de relais
+      status: Statut
+      title: Relais
     report_notes:
-      created_msg: Note de signalement créée avec succès !
-      destroyed_msg: Note de signalement effacée avec succès !
+      created_msg: Note de signalement créée avec succès !
+      destroyed_msg: Note de signalement effacée avec succès !
     reports:
       account:
         note: note
         report: signaler
       action_taken_by: Intervention de
       are_you_sure: Êtes vous certain⋅e ?
-      assign_to_self: Me l'assigner
+      assign_to_self: Me l’assigner
       assigned: Modérateur assigné
       comment:
         none: Aucun
       created_at: Signalé
-      id: ID
       mark_as_resolved: Marquer comme résolu
       mark_as_unresolved: Marquer comme non-résolu
       notes:
@@ -286,36 +360,43 @@ fr:
         placeholder: Décrivez quelles actions ont été prises, ou toute autre mise à jour…
       reopen: Ré-ouvrir le signalement
       report: 'Signalement #%{id}'
-      report_contents: Contenu
       reported_account: Compte signalé
       reported_by: Signalé par
       resolved: Résolus
-      resolved_msg: Signalement résolu avec succès !
-      silence_account: Masquer le compte
+      resolved_msg: Signalement résolu avec succès !
       status: Statut
-      suspend_account: Suspendre le compte
-      target: Cible
       title: Signalements
       unassign: Dés-assigner
       unresolved: Non résolus
       updated_at: Mis à jour
-      view: Voir
     settings:
       activity_api_enabled:
-        desc_html: Nombre de statuts affichés localement, d'utilisateurs actifs et de nouveaux enregistrements dans les registres hebdomadaires
-        title: Publier des statistiques agrégées sur l'activité des utilisateurs
+        desc_html: Nombre de statuts affichés localement, d’utilisateur·ice·s actif·ve·s et de nouveaux enregistrements dans les registres hebdomadaires
+        title: Publier des statistiques agrégées sur l’activité des utilisateur·ice·s
       bootstrap_timeline_accounts:
-        desc_html: Séparez les noms d’utilisateur·ice par des virgules. Ne fonctionne qu’avec des comptes locaux et non-verrouillés. Si laissé vide, tous les administrateur⋅ice⋅s locaux sont sélectionné⋅e⋅s.
+        desc_html: Séparez les noms d’utilisateur·ice par des virgules. Ne fonctionne qu’avec des comptes locaux et non verrouillés. Si laissé vide, tous les administrateur⋅ice⋅s locaux sont sélectionné⋅e⋅s.
         title: Abonnements par défaut pour les nouveaux·elles utilisateur·ice·s
       contact_information:
         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
       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
-        title: Image d'en-tête
+        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
+        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
+        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
+      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
       registrations:
         closed_message:
           desc_html: Affiché sur la page d’accueil lorsque les inscriptions sont fermées<br>Vous pouvez utiliser des balises HTML
@@ -330,17 +411,20 @@ fr:
           desc_html: Autoriser tout le monde à créer un compte
           title: Ouvrir les inscriptions
       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. Si non, seuls les pouets locaux sont affichés.
+        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.
         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
+        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 et dans les méta-balises. Vous pouvez utiliser des balises HTML, en particulier <code>&lt;a&gt;</code> et <code>&lt;em&gt;</code>.
+        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
       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
+      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
       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é
@@ -362,6 +446,7 @@ fr:
       media:
         title: Médias
       no_media: Aucun média
+      no_status_selected: Aucun statut n’a été modifié car aucun n’a été sélectionné
       title: État du compte
       with_media: avec médias
     subscriptions:
@@ -371,17 +456,31 @@ fr:
       last_delivery: Dernière livraison
       title: WebSub
       topic: Sujet
+    tags:
+      accounts: Comptes
+      hidden: Masqué
+      hide: Masquer dans l'annuaire
+      name: Hashtag
+      title: Hashtags
+      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
   admin_mailer:
     new_report:
       body: "%{reporter} a signalé %{target}"
-      body_remote: Quelqu'un de %{domain} a signalé %{target}
+      body_remote: Quelqu’un de %{domain} a signalé %{target}
       subject: Nouveau signalement sur %{instance} (#%{id})
   application_mailer:
     notification_preferences: Modifier les préférences de courriel
     salutation: "%{name},"
     settings: 'Changer les préférences courriel : %{link}'
-    view: 'Voir :'
+    view: 'Voir :'
     view_profile: Voir le profil
     view_status: Afficher le statut
   applications:
@@ -393,7 +492,7 @@ fr:
     warning: Soyez prudent⋅e avec ces données. Ne les partagez pas !
     your_token: Votre jeton d’accès
   auth:
-    agreement_html: En vous inscrivant, vous souscrivez <a href="%{rules_path}">aux règles de l’instance</a> et à <a href="%{terms_path}">nos conditions d’utilisation</a>.
+    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>.
     change_password: Mot de passe
     confirm_email: Confirmer mon adresse mail
     delete_account: Supprimer le compte
@@ -411,7 +510,7 @@ fr:
       cas: CAS
       saml: SAML
     register: S’inscrire
-    register_elsewhere: S'inscrire sur un autre serveur
+    register_elsewhere: S’inscrire sur un autre serveur
     resend_confirmation: Envoyer à nouveau les consignes de confirmation
     reset_password: Réinitialiser le mot de passe
     security: Sécurité
@@ -420,8 +519,8 @@ fr:
     already_following: Vous suivez déjà ce compte
     error: Malheureusement, il y a eu une erreur en cherchant les détails du compte distant
     follow: Suivre
-    follow_request: 'Vous avez demandé à suivre :'
-    following: 'Youpi ! Vous suivez  :'
+    follow_request: 'Vous avez demandé à suivre :'
+    following: 'Youpi ! Vous suivez maintenant  :'
     post_follow:
       close: Ou bien, vous pouvez fermer cette fenêtre.
       return: Afficher le profil de l’utilisateur⋅ice
@@ -447,8 +546,18 @@ 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-lignes 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 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_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
+    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 !
+    people:
+      one: "%{count} personne"
+      other: "%{count} personne"
   errors:
     '403': Vous n’avez pas accès à cette page.
     '404': La page que vous recherchez n’existe pas.
@@ -460,20 +569,38 @@ fr:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">applications natives</a> pour Mastodon pour votre plate-forme.
+    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.
   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.
-      in_progress: Élaboration de votre archive....
+      in_progress: Création de votre archive…
       request: Demandez vos archives
       size: Taille
     blocks: Vous bloquez
     csv: CSV
+    domain_blocks: Bloqueurs de domaine
     follows: Vous suivez
+    lists: Listes
     mutes: Vous masquez
     storage: Médias stockés
+  filters:
+    contexts:
+      home: Accueil
+      notifications: Notifications
+      public: Fils publics
+      thread: Conversations
+    edit:
+      title: Éditer le filtre
+    errors:
+      invalid_context: Contexte invalide ou insuffisant
+      invalid_irreversible: Le filtrage irréversible ne fonctionne que pour l’accueil et les notifications
+    index:
+      delete: Effacer
+      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.
@@ -486,9 +613,13 @@ fr:
     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:
     changes_saved_msg: Les modifications ont été enregistrées avec succès !
-    powered_by: propulsé par %{link}
+    copy: Copier
     save_changes: Enregistrer les modifications
     validation_errors:
       one: Quelque chose ne va pas ! Vérifiez l’erreur ci-dessous
@@ -514,6 +645,7 @@ fr:
       '86400': 1 jour
     expires_in_prompt: Jamais
     generate: Générer
+    invited_by: 'Vous avez été invité·e par :'
     max_uses:
       one: 1 usage
       other: "%{count} usages"
@@ -523,8 +655,6 @@ fr:
       expires_at: Expire
       uses: Utilise
     title: Inviter des gens
-  landing_strip_html: <strong>%{name}</strong> utilise %{link_to_root_path}. Vous pouvez læ suivre et interagir si vous possédez un compte quelque part dans le "fediverse".
-  landing_strip_signup_html: Si ce n’est pas le cas, vous pouvez <a href="%{sign_up_path}">en créer un ici</a>.
   lists:
     errors:
       limit: Vous avez atteint le nombre maximum de listes
@@ -533,26 +663,26 @@ fr:
       images_and_video: Impossible de joindre une vidéo à un statut contenant déjà des images
       too_many: Impossible de joindre plus de 4 fichiers
   migrations:
-    acct: utilisateur@domaine du nouveau compte
-    currently_redirecting: 'Votre profile va être redirigé vers :'
+    acct: profil@domaine du nouveau compte
+    currently_redirecting: 'Votre profil va être redirigé vers :'
     proceed: Enregistrer
-    updated_msg: Les paramètres de votre migration de compte ont été mis à jour avec succès !
+    updated_msg: Les paramètres de votre migration de compte ont été mis à jour avec succès !
   moderation:
     title: Modération
   notification_mailer:
     digest:
       action: Voir toutes les notifications
-      body: 'Voici ce que vous avez raté sur ${instance} depuis votre dernière visite le %{since} :'
-      mention: "%{name} vous a mentionné⋅e dans :"
+      body: Voici un bref résumé des messages que vous auriez raté depuis votre dernière visite le %{since}
+      mention: "%{name} vous a mentionné⋅e dans :"
       new_followers_summary:
         one: Vous avez un⋅e nouvel⋅le abonné⋅e ! Youpi !
         other: Vous avez %{count} nouveaux⋅elles abonné⋅e·s ! Incroyable !
       subject:
         one: "Une nouvelle notification depuis votre dernière visite \U0001F418"
         other: "%{count} nouvelles notifications depuis votre dernière visite \U0001F418"
-      title: Pendant votre absence...
+      title: Pendant votre absence…
     favourite:
-      body: "%{name} a ajouté votre post à ses favoris :"
+      body: "%{name} a ajouté votre pouet à ses favoris :"
       subject: "%{name} a ajouté votre post à ses favoris"
       title: Nouveau favori
     follow:
@@ -560,17 +690,17 @@ fr:
       subject: "%{name} vous suit"
       title: Nouvel·le abonné·e
     follow_request:
-      action: Gérer les demandes d'abonnement
+      action: Gérer les demandes d’abonnement
       body: "%{name} a demandé à vous suivre"
       subject: 'Abonné⋅es en attente : %{name}'
-      title: Nouvelle demande d'abonnement
+      title: Nouvelle demande d’abonnement
     mention:
       action: Répondre
-      body: "%{name} vous a mentionné⋅e dans :"
+      body: "%{name} vous a mentionné⋅e dans :"
       subject: "%{name} vous a mentionné·e"
       title: Nouvelle mention
     reblog:
-      body: "%{name} a partagé votre statut :"
+      body: "%{name} a partagé votre statut :"
       subject: "%{name} a partagé votre statut"
       title: Nouveau partage
   number:
@@ -596,14 +726,27 @@ fr:
     publishing: Publication
     web: Web
   remote_follow:
-    acct: Entrez votre pseudo@instance depuis lequel vous voulez suivre cet·te utilisateur⋅ice
+    acct: Entrez l’adresse profil@instance depuis laquelle vous voulez vous abonner
     missing_resource: L’URL de redirection n’a pas pu être trouvée
-    proceed: Continuez pour suivre
-    prompt: 'Vous allez suivre :'
+    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
+    prompt: 'Vous allez suivre :'
+    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:
+      prompt: 'Vous souhaitez mettre ce pouet en favori :'
+    reblog:
+      prompt: 'Vous souhaitez repartager ce pouet :'
+    reply:
+      prompt: 'Vous souhaitez répondre à ce pouet :'
   remote_unfollow:
     error: Erreur
     title: Titre
     unfollowed: Non-suivi
+  scheduled_statuses:
+    over_daily_limit: Vous avez dépassé la limite de %{limit} pouets planifiés pour ce jour
+    over_total_limit: Vous avez dépassé la limite de %{limit} pouets planifiés
+    too_soon: La date planifiée doit être dans le futur
   sessions:
     activity: Dernière activité
     browser: Navigateur
@@ -662,7 +805,7 @@ fr:
     your_apps: Vos applications
   statuses:
     attached:
-      description: 'Attaché : %{attached}'
+      description: 'Attaché : %{attached}'
       image:
         one: "%{count} image"
         other: "%{count} images"
@@ -670,10 +813,11 @@ fr:
         one: "%{count} vidéo"
         other: "%{count} vidéos"
     boosted_from_html: Repartagé depuis %{acct_link}
-    content_warning: 'Attention au contenu : %{warning}'
+    content_warning: 'Avertissement sur le contenu : %{warning}'
     disallowed_hashtags:
-      one: 'contient un hashtag désactivé : %{tags}'
-      other: 'contient les hashtag désactivés : %{tags}'
+      one: 'contient un hashtag désactivé : %{tags}'
+      other: 'contient les hashtags désactivés : %{tags}'
+    language_detection: Détecter automatiquement la langue
     open_in_web: Ouvrir sur le web
     over_character_limit: limite de caractères dépassée de %{max} caractères
     pin_errors:
@@ -682,6 +826,7 @@ fr:
       private: Les statuts non-publics ne peuvent pas être épinglés
       reblog: Un partage ne peut pas être épinglé
     show_more: Afficher plus
+    sign_in_to_participate: Inscrivez-vous pour prendre part à la conversation
     title: '%{name} : "%{quote}"'
     visibilities:
       private: Abonné⋅e⋅s uniquement
@@ -691,12 +836,92 @@ fr:
       unlisted: Public sans être affiché sur le fil public
       unlisted_long: Tout le monde peut voir vos statuts mais ils ne seront pas sur listés sur les fils publics
   stream_entries:
-    click_to_show: Cliquer pour afficher
     pinned: Pouet épinglé
     reblogged: a partagé
     sensitive_content: Contenu sensible
   terms:
-    title: "%{instance} Conditions d’utilisations et politique de confidentialité"
+    body_html: |
+      <h2>Politique de confidentialité</h2>
+      <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>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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Que faisons-nous des informations que nous collectons ?</h3>
+
+      <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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">Comment protégeons-nous vos informations ?</h3>
+
+      <p>Nous mettons en œuvre une variété de mesures de sécurité afin de garantir la sécurité de vos informations personnelles quand vous les saisissez, les soumettez et les consultez. Entre autres choses, votre session de navigation ainsi que le trafic entre votre application et l’API sont sécurisés à l’aide de TLS tandis que votre mot de passe est haché en utilisant un puissant algorithme à sens unique. Vous pouvez également activer l’authentification à deux facteurs pour sécuriser encore plus l’accès à votre compte.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">Quelle est notre politique de conservation des données ?</h3>
+
+      <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>
+      </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>
+
+      <p>Vous pouvez, à n’importe quel moment, supprimer votre compte de manière définitive.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Utilisons-nous des témoins de connexion ?</h3>
+
+      <p>Oui. Les témoins de connexion sont de petits fichiers qu’un site ou un service transféres sur le disque dur de votre ordinateur via votre navigateur web (si vous l’avez autorisé). Ces témoins permettent au site de reconnaître votre navigateur et de, dans le cas où vous possédez un compte, de vous associer avec ce dernier.</p>
+
+      <p>Nous utilisons les témoins de connexion comme un moyen de comprendre et de nous souvenir de vos préférences pour vos prochaines visites.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Divulguons-nous des informations à des tierces parties ?</h3>
+
+      <p>Nous ne vendons, n’échangeons ou ne transférons d’une quelque manière que soit des informations permettant de vous identifier personnellement. Cela n’inclut pas les tierces parties de confiance qui nous aident à opérer ce site, à conduire nos activités commerciales ou à vous servir, tant qu’elles acceptent de garder ces informations confidentielles. Nous sommes également susceptibles de partager vos informations quand nous pensons que c’est nécessaire pour nous conformer à la loi, pour appliquer les politiques de notre site ainsi que pour défendre nos droits, notre propriété, notre sécurité et celles et ceux d’autres personnes.</p>
+
+      <p>Votre contenu public peut être téléchargé par d’autres serveurs du réseau. Dans le cas où vos abonné·e·s et vos destinataires résideraient sur des serveurs différents du vôtre, vos posts publics et abonné·e·s uniquement peuvent être délivrés vers les serveurs de vos abonné·e·s tandis que vos messages directs sont délivrés aux serveurs de vos destinataires.</p>
+
+      <p>Quand vous autorisez une application à utiliser votre compte, en fonction de l’étendue des permissions que vous approuvez, il est possible qu’elle puisse accéder aux informations publiques de votre profil, votre liste d’abonnements, votre liste d’abonné·e·s, vos listes, tout vos posts et vos favoris. Les applications ne peuvent en aucun cas accéder à votre adresse électronique et à votre mot de passe.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Utilisation de ce site par les enfants</h3>
+
+      <p>Si ce serveur est situé dans dans l’UE ou l’EEE : Notre site, produits et services sont tous destinés à des personnes âgées de 16 ans ou plus. Si vous avez moins de 16 ans, en application du RGPD (<a href="https://fr.wikipedia.org/wiki/R%C3%A8glement_g%C3%A9n%C3%A9ral_sur_la_protection_des_donn%C3%A9es">Règlement Général sur la Protection des Données</a>), merci de ne pas utiliser ce site.</p>
+
+      <p>Si ce serveur est situé dans aux États-Unis d’Amérique : Notre site, produits et services sont tous destinés à des personnes âgées de 13 ans ou plus. Si vous avez moins de 13 ans, en application du COPPA (<a href="https://fr.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>), merci de ne pas utiliser ce site.</p>
+
+      <p>Les exigences légales peuvent être différentes si ce serveur se trouve dans une autre juridiction.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Modifications de notre politique de confidentialité</h3>
+
+      <p>Dans le cas où nous déciderions de changer notre politique de confidentialité, nous posterons les modifications sur cette page.</p>
+
+      <p>Ce document est publié sous lincence CC-BY-SA. Il a été mis à jours pour la dernière fois le 7 mars 2018.</p>
+
+      <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
@@ -704,6 +929,7 @@ fr:
   time:
     formats:
       default: "%d %b %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Entrez le code généré par votre application pour confirmer
     description_html: Si vous activez <strong>l’identification à deux facteurs</strong>, vous devrez être en possession de votre téléphone afin de générer un code de connexion.
@@ -713,8 +939,8 @@ fr:
     enabled_success: Identification à deux facteurs activée avec succès
     generate_recovery_codes: Générer les codes de récupération
     instructions_html: "<strong>Scannez ce QR code grâce à Google Authenticator, Authy ou une application similaire sur votre téléphone</strong>. Désormais, cette application génèrera des jetons que vous devrez saisir à chaque connexion."
-    lost_recovery_codes: Les codes de récupération vous permettent de retrouver les accès à votre comptre si vous perdez votre téléphone. Si vous perdez vos codes de récupération, vous pouvez les générer à nouveau ici. Vos anciens codes de récupération seront invalidés.
-    manual_instructions: 'Si vous ne pouvez pas scanner ce QR code et devez l’entrer manuellement, voici le secret en clair :'
+    lost_recovery_codes: Les codes de récupération vous permettent de retrouver les accès à votre compte si vous perdez votre téléphone. Si vous perdez vos codes de récupération, vous pouvez les générer à nouveau ici. Vos anciens codes de récupération seront invalidés.
+    manual_instructions: 'Si vous ne pouvez pas scanner le code QR et devez l’entrer manuellement, voici le secret en texte-plein :'
     recovery_codes: Codes de récupération
     recovery_codes_regenerated: Codes de récupération régénérés avec succès
     recovery_instructions_html: Si vous perdez l’accès à votre téléphone, vous pouvez utiliser un des codes de récupération ci-dessous pour retrouver l’accès à votre compte. <strong>Conservez les codes de récupération en sécurité</strong>. Par exemple, en les imprimant et en les stockant avec vos autres documents importants.
@@ -722,30 +948,49 @@ fr:
     wrong_code: Les codes entrés sont incorrects ! L’heure du serveur et celle de votre appareil sont-elles correctes ?
   user_mailer:
     backup_ready:
-      explanation: Vous avez demandé une sauvegarde complète de votre compte Mastodon. Elle est maintenant prête à être téléchargée !
+      explanation: Vous avez demandé une sauvegarde complète de votre compte Mastodon. Elle est maintenant prête à être téléchargée !
       subject: Votre archive est prête à être téléchargée
-      title: Retrait de l'archive
+      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.
+        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:
+        disable: Votre compte %{acct} a été gelé
+        none: Avertissement pour %{acct}
+        silence: Votre compte %{acct} a été limité
+        suspend: Votre compte %{acct} a été suspendu
+      title:
+        disable: Compte gelé
+        none: Avertissement
+        silence: Compte limité
+        suspend: Compte suspendu
     welcome:
       edit_profile_action: Configuration du profil
-      edit_profile_step: Vous pouvez personnaliser votre profil en téléchargeant un avatar, une image d'en-tête, en changeant votre pseudo et plus encore. Si vous souhaitez examiner les nouveaux abonnés avant qu'ils ne soient autorisés à vous suivre, vous pouvez verrouiller votre compte.
+      edit_profile_step: Vous pouvez personnaliser votre profil en téléchargeant un avatar, une image d’en-tête, en changeant votre pseudo et plus encore. Si vous souhaitez examiner les nouveaux·lles abonné·e·s avant qu’il·elle·s ne soient autorisé·e·s à vous suivre, vous pouvez verrouiller votre compte.
       explanation: Voici quelques conseils pour vous aider à démarrer
       final_action: Commencer à publier
-      final_step: 'Commencez à poster ! Même sans abonné·es, vos messages publics peuvent être vus par d''autres, par exemple sur la chronologie locale et dans les hashtags. Vous pouvez vous présenter sur le hashtag #introductions.'
-      full_handle: Votre pleine maîtrise
-      full_handle_hint: C'est ce que vous diriez à vos amis pour qu'ils puissent vous envoyer un message ou vous suivre à partir d'une autre instance.
+      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.
       review_preferences_action: Modifier les préférences
-      review_preferences_step: Assurez-vous de définir vos préférences, telles que les courriels que vous aimeriez recevoir ou le niveau de confidentialité auquel vous aimeriez que vos messages soient soumis par défaut. Si vous n'avez pas le mal des transports, vous pouvez choisir d'activer la lecture automatique GIF.
+      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
-      tip_bridge_html: Si vous venez de Twitter, vous pouvez retrouver vos amis sur Mastodon en utilisant le <a href="%{bridge_url}">bridge app</a>. Cela ne fonctionne que s'ils ont aussi utilisé cette application !
-      tip_federated_timeline: La chronologie fédérée est une vue en direct du réseau Mastodon. Mais elle n'inclut que les personnes auxquelles vos voisin·es sont abonné·es, donc elle n'est pas complète.
-      tip_following: Vous suivez les administrateurs et administratrices de votre serveur par défaut. Pour trouver d'autres personnes intéressantes, consultez les chronologies locales et fédérées.
-      tip_local_timeline: La chronologie locale est une vue des personnes sur %{instance}. Ce sont vos voisines et voisins immédiats !
-      tip_mobile_webapp: Si votre navigateur mobile vous propose d'ajouter Mastodon à votre écran d'accueil, vous pouvez recevoir des notifications. Il agit comme une application native de bien des façons !
+      tip_federated_timeline: La fil public global est une vue en direct du réseau Mastodon. Mais elle n’inclut que les personnes auxquelles vos voisin·es sont abonné·e·s, donc elle n’est pas complète.
+      tip_following: Vous suivez les administrateur·rice·s de votre serveur par défaut. Pour trouver d’autres personnes intéressantes, consultez les fils publics local et global.
+      tip_local_timeline: Le fil public local est une vue des personnes sur %{instance}. Ce sont vos voisines et voisins immédiats !
+      tip_mobile_webapp: Si votre navigateur mobile vous propose d’ajouter Mastodon à votre écran d’accueil, vous pouvez recevoir des notifications. Il agit comme une application native de bien des façons !
       tips: Astuces
-      title: Bienvenue à bord, %{name} !
+      title: Bienvenue à bord, %{name} !
   users:
+    follow_limit_reached: Vous ne pouvez pas suivre plus de %{limit} personnes
     invalid_email: L’adresse courriel est invalide
     invalid_otp_token: Le code d’authentification à deux facteurs est invalide
     otp_lost_help_html: Si vous perdez accès aux deux, vous pouvez contacter %{email}
     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 :'
+    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 :'
+    verification: Vérification
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index 3963bf3e6b4de8d758b1c568fcd1987038933c72..8e0a9aeb1be78eb3bf13115d632f85acbdabcc5c 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -5,13 +5,13 @@ gl:
     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
     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í.
     contact: Contacto
     contact_missing: Non establecido
     contact_unavailable: N/A
-    description_headline: Qué é %{domain}?
-    domain_count_after: outras instancias
-    domain_count_before: Conectada a
+    documentation: Documentación
     extended_description_html: |
       <h3>Un bo lugar para regras</h3>
       <p>A descrición extendida aínda non se proporcionou.</p>
@@ -22,31 +22,47 @@ gl:
       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 aplicativos 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_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
     generic_description: "%{domain} é un servidor na rede"
     hosted_on: Mastodon aloxado en %{domain}
     learn_more: Coñeza máis
     other_instances: Listado de instancias
+    privacy_policy: Política de intimidade
     source_code: Código fonte
-    status_count_after: estados
+    status_count_after:
+      one: estado
+      other: estados
     status_count_before: Que publicaron
-    user_count_after: usuarias
+    terms: Termos do servizo
+    user_count_after:
+      one: usuaria
+      other: usuarias
     user_count_before: Fogar de
     what_is_mastodon: Qué é Mastodon?
   accounts:
+    choices_html: 'Eleccións de %{name}:'
     follow: Seguir
-    followers: Seguidoras
+    followers:
+      one: Seguidora
+      other: Seguidoras
     following: Seguindo
+    joined: Uneuse %{date}
+    last_active: última actividade
+    link_verified_on: A propiedade de esta ligazón foi comprobada en %{date}
     media: Medios
     moved_html: "%{name} mudouse a %{new_profile_link}:"
     network_hidden: A información non está dispoñible
     nothing_here: Nada por aquí!
     people_followed_by: Personas que segue %{name}
     people_who_follow: Personas que seguen a %{name}
-    posts: Mensaxes
+    pin_errors:
+      following: Debe seguir a persoa que intenta recomendar
+    posts:
+      one: Toot
+      other: Toots
+    posts_tab_heading: Toots
     posts_with_replies: Toots e respostas
-    remote_follow: Seguimento remoto
     reserved_username: O nome de usuaria está reservado
     roles:
       admin: Admin
@@ -54,6 +70,9 @@ gl:
       moderator: Mod
     unfollow: Deixar de seguir
   admin:
+    account_actions:
+      action: Realizar acción
+      title: Realizar acción de moderación sobre %{acct}
     account_moderation_notes:
       create: Deixar nota
       created_msg: Nota a moderación creada con éxito!
@@ -65,14 +84,15 @@ gl:
       by_domain: Dominio
       change_email:
         changed_msg: Cambiouse correctamente o correo-e da conta!
-        current_email: Correo-e actual
-        label: Cambiar correo-e
-        new_email: Novo correo-e
-        submit: Cambiar correo-e
-        title: Cambiar o correo-e de %{username}
+        current_email: Correo actual
+        label: Cambiar correo
+        new_email: Novo correo
+        submit: Cambiar correo
+        title: Cambiar o correo de %{username}
       confirm: Confirmar
       confirmed: Confirmado
       confirming: Confirmar
+      deleted: Eliminado
       demote: Degradar
       disable: Deshabilitar
       disable_two_factor_authentication: Deshabilitar 2FA
@@ -80,16 +100,19 @@ gl:
       display_name: Mostrar nome
       domain: Dominio
       edit: Editar
-      email: E-mail
-      email_status: Estado del correo electrónico
+      email: Email
+      email_status: Estado do correo
       enable: Habilitar
       enabled: Habilitado
       feed_url: URL fonte
       followers: Seguidoras
       followers_url: URL das seguidoras
       follows: Segue
+      header: Cabeceira
       inbox_url: URL da Caixa de entrada
+      invited_by: Convidada por
       ip: IP
+      joined: Uniuse
       location:
         all: Todo
         local: Local
@@ -99,6 +122,7 @@ gl:
       media_attachments: Anexos de medios
       memorialize: Convertir a lembranza
       moderation:
+        active: Activa
         all: Todo
         silenced: Acalado
         suspended: Suspendido
@@ -106,20 +130,18 @@ gl:
       moderation_notes: Notas de moderación
       most_recent_activity: Actividade máis recente
       most_recent_ip: IP máis recente
+      no_limits_imposed: Sen límites impostos
       not_subscribed: Non suscrita
-      order:
-        alphabetic: Alfabética
-        most_recent: Máis recente
-        title: Orde
       outbox_url: URL caixa de saída
-      perform_full_suspension: Suspender completamente
+      perform_full_suspension: Suspender
       profile_url: URL do perfil
       promote: Promocionar
       protocol: Protocolo
       public: Público
       push_subscription_expires: A suscrición PuSH caduca
-      redownload: Actualizar avatar
+      redownload: Actualizar perfil
       remove_avatar: Eliminar avatar
+      remove_header: Eliminar cabeceira
       resend_confirmation:
         already_confirmed: Este usuario ya está confirmado
         send: Reenviar el correo electrónico de confirmación
@@ -137,28 +159,32 @@ gl:
       search: Busca
       shared_inbox_url: URL da caixa de entrada compartida
       show:
-        created_reports: Informes creados por esta conta
-        report: informar
-        targeted_reports: Informes feitos sobre esta conta
+        created_reports: Informes creados
+        targeted_reports: Informes feitos por outros
       silence: Acalar
+      silenced: Acalada
       statuses: Estados
       subscribe: Subscribir
+      suspended: Suspendida
       title: Contas
-      unconfirmed_email: Correo-e non confirmado
+      unconfirmed_email: Correo non confirmado
       undo_silenced: Desfacer acalar
       undo_suspension: Desfacer suspensión
       unsubscribe: Non subscribir
       username: Nome de usuaria
+      warn: Aviso
       web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} asignou o informe %{target} a ela misma"
         change_email_user: "%{name} cambiou o enderezo de correo-e da usuaria %{target}"
         confirm_user: "%{name} comfirmou o enderezo de correo da usuaria %{target}"
+        create_account_warning: "%{name} enviou un aviso sobre %{target}"
         create_custom_emoji: "%{name} subeu un novo emoji %{target}"
         create_domain_block: "%{name} bloqueou o dominio %{target}"
         create_email_domain_block: "%{name} engadeu a lista negra o dominio de correo %{target}"
         demote_user: "%{name} degradou a usuaria %{target}"
+        destroy_custom_emoji: "%{name} destruíu emoji %{target}"
         destroy_domain_block: "%{name} desbloqueou o dominio %{target}"
         destroy_email_domain_block: "%{name} meteu na lista blanca de correo o dominio %{target}"
         destroy_status: "%{name} eliminou o estado de %{target}"
@@ -180,6 +206,7 @@ gl:
         unsuspend_account: "%{name} activou a conta de %{target}"
         update_custom_emoji: "%{name} actualizou emoji %{target}"
         update_status: "%{name} actualizou un estado de %{target}"
+      deleted_status: "(estado eliminado)"
       title: Rexistro de auditoría
     custom_emojis:
       by_domain: Dominio
@@ -197,17 +224,39 @@ gl:
       image_hint: PNG ate 50KB
       listed: Listado
       new:
-        title: Engadir novo emoji personalizado
+        title: Engadir novo emoji persoalizado
       overwrite: Sobrescribir
       shortcode: Código corto
       shortcode_hint: Cando menos 2 caracteres, só caracteres alfanuméricos e subliñados
-      title: Emojis personalizados
+      title: Emojis persoalizados
       unlisted: Non listado
       update_failed_msg: Non se puido actualizar ese emoji
       updated_msg: Actualizouse correctamente o emoji!
       upload: Subir
+    dashboard:
+      backlog: traballos respaldados
+      config: Axustes
+      feature_deletions: Borrado de contas
+      feature_invites: Ligazóns de convite
+      feature_profile_directory: Directorio do perfil
+      feature_registrations: Rexistros
+      feature_relay: Repetidores de federación
+      features: Características
+      hidden_service: Federación con servizos ocultos
+      open_reports: informes abertos
+      recent_users: Usuarias recentes
+      search: Busca de texto completo
+      single_user_mode: Modo de usuario individual
+      software: Software
+      space: Uso de espazo
+      title: Taboleiro
+      total_users: total de usuarias
+      trends: Tendencias
+      week_interactions: interaccións en esta semana
+      week_users_active: activas estas semana
+      week_users_new: usuarias esta semana
     domain_blocks:
-      add_new: Engadir novo
+      add_new: Engadir novo bloqueo de dominio
       created_msg: Estase a procesar o bloqueo do dominio
       destroyed_msg: Desfixose a acción de bloqueo de dominio
       domain: Dominio
@@ -222,11 +271,13 @@ gl:
         title: Novo bloqueo de dominio
       reject_media: Rexeitar ficheiros de medios
       reject_media_hint: Eliminar ficheiros de medios almacenados localmente e rexeita descargalos no futuro. Irrelevante para as suspensións
-      severities:
-        noop: Ningún
-        silence: Silenciar
-        suspend: Suspender
-      severity: Severidade
+      reject_reports: Rexeitar informes
+      reject_reports_hint: Ignorar todos os informes procedentes de este dominio. Irrelevante para as suspensións
+      rejecting_media: rexeitando ficheiros de medios
+      rejecting_reports: rexeitando informes
+      severity:
+        silence: acalado
+        suspend: suspendido
       show:
         affected_accounts:
           one: Afectoulle a unha conta na base de datos
@@ -236,8 +287,7 @@ gl:
           suspend: Non suspender todas as contas existentes de este dominio
         title: Desfacer o bloqueo de dominio para %{domain}
         undo: Desfacer
-      title: Bloqueos de domino
-      undo: Desfacer
+      undo: Desfacer bloqueo de dominio
     email_domain_blocks:
       add_new: Engadir novo
       created_msg: Engadeuse correctamente o dominio de email a lista negra
@@ -248,19 +298,47 @@ gl:
         create: Engadir dominio
         title: Nova entrada la lista negra de e-mail
       title: Lista negra de E-mail
+    followers:
+      back_to_account: Voltar a Conta
+      title: Seguidoras de %{acct}
     instances:
-      account_count: Contas coñecidas
-      domain_name: Dominio
-      reset: Restablecer
-      search: Buscar
-      title: Instancias coñecidas
+      delivery_available: A entrega está dispoñible
+      known_accounts:
+        one: "%{count} conta coñecida"
+        other: "%{count} contas coñecidas"
+      moderation:
+        all: Todo
+        limited: Limitado
+        title: Moderación
+      title: Federación
+      total_blocked_by_us: Bloqueado por nós
+      total_followed_by_them: Seguidas por eles
+      total_followed_by_us: Seguidas por nós
+      total_reported: Informes sobre elas
+      total_storage: Anexos de medios
     invites:
+      deactivate_all: Desactivar todo
       filter:
         all: Todo
         available: Dispoñible
         expired: Cadudado
         title: Filtro
       title: Convida
+    relays:
+      add_new: Engadir un novo repetidor
+      delete: Eliminar
+      description_html: Un <strong>repetidor da federación</strong> é un servidor intermedio que intercambia grandes volumes de toots públicos entre servidores que se suscriban e publiquen nel. <strong>Pode axudar a servidores pequenos e medios a descubrir contido no fediverso</strong>, o que de outro xeito precisaría que as usuarias locais seguisen a outra xente en servidores remotos.
+      disable: Desactivar
+      disabled: Desactivada
+      enable: Activar
+      enable_hint: Unha vez activado, o seu servidor suscribirase a todos os toots públicos de este servidor, e tamén comezará a eviar a el os toots públicos do servidor.
+      enabled: Activada
+      inbox_url: URL do repetidor
+      pending: Agardando polo permiso do repetidor
+      save_and_enable: Gardar e activar
+      setup: Configurar a conexión ao repetidor
+      status: Estado
+      title: Repetidores
     report_notes:
       created_msg: Creouse correctamente a nota do informe!
       destroyed_msg: Nota do informe eliminouse con éxito!
@@ -275,7 +353,6 @@ gl:
       comment:
         none: Nada
       created_at: Reportado
-      id: ID
       mark_as_resolved: Marcar como resolto
       mark_as_unresolved: Marcar como non resolto
       notes:
@@ -286,20 +363,15 @@ gl:
         placeholder: Describe qué medidas foron tomadas, ou calquer outra información relacionada...
       reopen: Voltar a abrir o informe
       report: 'Informe #%{id}'
-      report_contents: Contidos
       reported_account: Conta reportada
       reported_by: Reportada por
       resolved: Resolto
       resolved_msg: Resolveuse con éxito o informe!
-      silence_account: Acalar conta
       status: Estado
-      suspend_account: Suspender conta
-      target: Obxetivo
       title: Informes
       unassign: Non asignar
       unresolved: Non resolto
       updated_at: Actualizado
-      view: Vista
     settings:
       activity_api_enabled:
         desc_html: Conta de estados publicados localmente, usuarias activas, e novos rexistros por semana
@@ -310,15 +382,24 @@ gl:
       contact_information:
         email: e-mail de traballo
         username: Nome de usuaria de contacto
+      custom_css:
+        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
         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
       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
+      profile_directory:
+        desc_html: Permitir que as usuarias poidan ser descubertas
+        title: Activar o directorio de perfil
       registrations:
         closed_message:
           desc_html: Mostrado na páxina de portada cando o rexistro está pechado. Pode utilizar etiquetas HTML
@@ -339,14 +420,17 @@ gl:
         desc_html: Mostrar unha insignia de membresía nunha páxina de usuaria
         title: Mostrar insigna de membresía
       site_description:
-        desc_html: Parágrafo de presentación na páxina principal e nas meta etiquetas. Pode utilizar etiquetas HTML, en particular <code>&lt;a&gt;</code> e <code>&lt;em&gt;</code>.
+        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
       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
-        title: Información extendida da personalización
+        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
       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 personalizados
+        title: Termos de servizo persoalizados
       site_title: Nome da instancia
       thumbnail:
         desc_html: Utilizado para vistas previsas vía OpenGraph e API. Recoméndase 1200x630px
@@ -365,6 +449,7 @@ gl:
       media:
         title: Medios
       no_media: Sen medios
+      no_status_selected: Non se cambiou ningún estado xa que ningún foi seleccionado
       title: Estados da conta
       with_media: con medios
     subscriptions:
@@ -374,7 +459,21 @@ gl:
       last_delivery: Última entrega
       title: WebSub
       topic: Asunto
+    tags:
+      accounts: Contas
+      hidden: Ocultas
+      hide: Ocultar do directorio
+      name: Etiqueta
+      title: Etiquetas
+      unhide: Mostrar en directorio
+      visible: Visible
     title: Administración
+    warning_presets:
+      add_new: Engadir novo
+      delete: Eliminar
+      edit: Editar
+      edit_preset: Editar aviso preestablecido
+      title: Xestionar avisos preestablecidos
   admin_mailer:
     new_report:
       body: "%{reporter} informou sobre %{target}"
@@ -396,7 +495,7 @@ 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: Rexistrándose acorda seguir <a href="%{rules_path}">as normas da instancia</a> e <a href="%{terms_path}">os termos do servizo</a>.
+    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>.
     change_password: Contrasinal
     confirm_email: Confirmar correo-e
     delete_account: Eliminar conta
@@ -407,7 +506,7 @@ gl:
     login: Conectar
     logout: Desconectar
     migrate_account: Mover a unha conta diferente
-    migrate_account_html: Si desexa redirixir esta conta hacia outra diferente, pode <a href="%{path}">configuralo aquí</a>.
+    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:
@@ -452,6 +551,16 @@ gl:
     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_title: Dispoñibilidade do contido espallado
+  directories:
+    directory: Directorio de perfil
+    enabled: Vostede está actualmente na lista do directorio.
+    enabled_but_waiting: Vostede optou por ser incluída no directorio, mais por agora non ten o número mínimo de seguidoras (%{min_followers}) para aparecer.
+    explanation: Descubra usuarias según o seu interese
+    explore_mastodon: Explorar %{title}
+    how_to_enable: Actualmente non solicitou ser incluída no directorio, pode facelo abaixo. Utilice etiquetas no texto de biografía para ser incluída baixo etiquetas específicas!
+    people:
+      one: "%{count} persoa"
+      other: "%{count} persoas"
   errors:
     '403': Non ten permiso para ver esta páxina.
     '404': A páxina que está a buscar non existe.
@@ -463,7 +572,7 @@ gl:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">apps nativas</a> para Mastodon da súa plataforma.
+    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.
   exports:
     archive_takeout:
       date: Data
@@ -474,7 +583,9 @@ gl:
       size: Tamaño
     blocks: A bloquear
     csv: CSV
+    domain_blocks: Bloqueos de dominio
     follows: A seguir
+    lists: Listas
     mutes: Acalou
     storage: Almacenamento de medios
   filters:
@@ -505,9 +616,13 @@ gl:
     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:
     changes_saved_msg: Cambios gardados correctamente!!
-    powered_by: grazas a %{link}
+    copy: Copiar
     save_changes: Gardar cambios
     validation_errors:
       one: Algo non está ben de todo! Por favor revise abaixo o erro
@@ -543,8 +658,6 @@ gl:
       expires_at: Caduca
       uses: Usos
     title: Convidar xente
-  landing_strip_html: "<strong>%{name}</strong> é unha usuaria en %{link_to_root_path}.  Pode seguila ou interactuar con ela si ten unha conta en algún lugar do fediverso."
-  landing_strip_signup_html: Si non, pode <a href="%{sign_up_path}">rexistrarse aquí</a>.
   lists:
     errors:
       limit: Acadou o número máximo de listas
@@ -616,15 +729,30 @@ gl:
     publishing: Publicando
     web: Web
   remote_follow:
-    acct: Introduza o seu nomedeusuaria@dominio desde onde quere facer seguimento
+    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
     no_account_html: Non ten unha conta? Pode <a href='%{sign_up_path}' target='_blank'>rexistrarse aquí</a>
     proceed: Proceda para seguir
     prompt: 'Vostede vai seguir:'
+    reason_html: "<strong>Por que é necesario este paso?</strong><code>%{instance}</code> podería non ser o servidor onde se rexistrou, así que precisamo redirixila primeiro ao seu servidor de orixe."
+  remote_interaction:
+    favourite:
+      proceed: Darlle a favorito
+      prompt: 'Vostede quere favorecer este toot:'
+    reblog:
+      proceed: Darlle a promocionar
+      prompt: 'Vostede quere promocionar este toot:'
+    reply:
+      proceed: Respostar
+      prompt: 'Vostede quere respostar a este toot:'
   remote_unfollow:
     error: Fallo
     title: Título
     unfollowed: Deixou de seguir
+  scheduled_statuses:
+    over_daily_limit: Excedeu o límite de %{limit} toots programados para ese día
+    over_total_limit: Excedeu o límite de %{limit} toots programados
+    too_soon: A data de programación debe estar no futuro
   sessions:
     activity: Última actividade
     browser: Navegador
@@ -667,7 +795,7 @@ gl:
     revoke_success: A sesión revocouse con éxito
     title: Sesións
   settings:
-    authorized_apps: Apps autorizados
+    authorized_apps: Apps autorizadas
     back: Voltar a Mastodon
     delete: Eliminación da conta
     development: Desenvolvemento
@@ -680,7 +808,7 @@ gl:
     preferences: Preferencias
     settings: Axustes
     two_factor_authentication: Validar Doble Factor
-    your_apps: Os seus aplicativos
+    your_apps: As súas aplicacións
   statuses:
     attached:
       description: 'Axenado: %{attached}'
@@ -704,6 +832,7 @@ gl:
       private: As mensaxes non-públicas non poden ser fixadas
       reblog: Non se poden fixar as mensaxes promovidas
     show_more: Mostrar máis
+    sign_in_to_participate: Conéctese para participar na conversa
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Só seguidoras
@@ -713,7 +842,6 @@ gl:
       unlisted: Non listado
       unlisted_long: Visible para calquera, pero non listado en liñas de tempo públicas
   stream_entries:
-    click_to_show: Pulse para mostrar
     pinned: Mensaxe fixada
     reblogged: promovida
     sensitive_content: Contido sensible
@@ -736,7 +864,7 @@ 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 personalizada.</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>
@@ -745,7 +873,7 @@ gl:
 
       <h3 id="protect">Cómo proxetemos os seus datos?</h3>
 
-      <p>Implementamos varias medidas de seguridade para protexer os seus datos personais cando introduce, envía ou accede a súa información personal. Entre outras medidas, a súa sesión de navegación, así como o tráfico entre os seus aplicativos e o API están aseguradas mediante SSL, e o seu contrasinal está camuflado utilizando un algoritmo potente de unha sóa vía. Pode habilitar a autenticación de doble factor para protexer o acceso a súa conta aínda máis.</p>
+      <p>Implementamos varias medidas de seguridade para protexer os seus datos personais cando introduce, envía ou accede a súa información persoal. Entre outras medidas, a súa sesión de navegación, así como o tráfico entre os seus aplicativos e o API están aseguradas mediante SSL, e o seu contrasinal está camuflado utilizando un algoritmo potente de unha sóa vía. Pode habilitar a autenticación de doble factor para protexer o acceso a súa conta aínda máis.</p>
 
       <hr class="spacer" />
 
@@ -807,6 +935,7 @@ gl:
   time:
     formats:
       default: "%d %b, %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Introducir o código xerado polo seu aplicativo de autenticación para confirmar
     description_html: Si habilita a <strong>autenticación de doble factor</strong>, a conexión pediralle estar en posesión do seu teléfono, que xerará testemuños para poder entrar.
@@ -828,9 +957,25 @@ gl:
       explanation: Solicitou un respaldo completo da súa conta de Mastodon. Xa está listo para descargar!
       subject: O seu ficheiro xa está listo para descargar
       title: Leve o ficheiro
+    warning:
+      explanation:
+        disable: Cando a súa conta está conxelada, os datos permanecen intactos, pero non pode levar a fin accións ate que se desbloquea.
+        silence: Mentras a conta está limitada, só a xente que actualmente a segue verá os seus toots en este servidor, e vostede podería estar excluída de varias listas públicas. Porén, outras persoas poderíana seguila de xeito manual.
+        suspend: A súa conta foi suspendida, e todos os seus toots e medios subidos foron eliminados de este servidor de xeito irreversible, e dos servidores onde tivese seguidoras.
+      review_server_policies: Revisar políticas do servidor
+      subject:
+        disable: A súa conta %{acct} foi conxelada
+        none: Aviso para %{acct}
+        silence: A súa conta %{acct} foi limitada
+        suspend: A súa conta %{acct} foi suspendida
+      title:
+        disable: Conta conxelada
+        none: Aviso
+        silence: Conta limitada
+        suspend: Conta suspendida
     welcome:
       edit_profile_action: Configurar perfil
-      edit_profile_step: Vostede pode personalizar o seu perfil subindo un avatar, cabeceira, cambiar o seu nome público e aínda máis. Si restrinxe a súa conta pode revisar a conta das personas que solicitan seguilas antes de permitirlles o acceso aos seus toots.
+      edit_profile_step: Vostede pode persoalizar o seu perfil subindo un avatar, cabeceira, cambiar o seu nome público e aínda máis. Si restrinxe a súa conta pode revisar a conta das personas que solicitan seguilas antes de permitirlles o acceso aos seus toots.
       explanation: Aquí ten alunhas endereitas para ir aprendendo
       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.'
@@ -839,7 +984,6 @@ gl:
       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
-      tip_bridge_html: Si chega desde a Twitter, pode atopar aos seus amigos en Mastodon utilizando o <a href="%{bridge_url}">aplicativo ponte</a>. Só funciona si eles tamén utilizan o aplicativo ponte!
       tip_federated_timeline: A liña temporal federada é unha visión ampla da rede Mastodon. Pero so inclúe xente a que segue xente que vostede segue, así que non é completa.
       tip_following: Por omisión vostede segue ao Admin do seu servidor. Para atopar máis xente interesante, mire nas liñas temporais local e federada.
       tip_local_timeline: A liña temporal local é unha ollada xeral sobre a xente en %{instance}. Son as súas veciñas máis próximas!
@@ -847,8 +991,12 @@ gl:
       tips: Consellos
       title: Benvida, %{name}!
   users:
+    follow_limit_reached: Non pode seguir a máis de %{limit} persoas
     invalid_email: O enderezo de correo non é válido
     invalid_otp_token: Código de doble-factor non válido
     otp_lost_help_html: Si perde o acceso a ambos, pode contactar con %{email}
     seamless_external_login: Está conectado a través de un servizo externo, polo que os axustes de contrasinal e correo-e non están dispoñibles.
     signed_in_as: 'Rexistrada como:'
+  verification:
+    explanation_html: 'Pode <strong>validarse a vostede mesma como a dona das ligazóns nos metadatos do seu perfil</strong>. Para esto, o sitio web ligado debe conter unha ligazón de retorno ao perfil de Mastodon. Esta ligazón de retorno <strong>ten que</strong> ter un atributo <code>rel="me"</code>. O texto da ligazón non importa. Aquí ten un exemplo:'
+    verification: Validación
diff --git a/config/locales/he.yml b/config/locales/he.yml
index 0ac1787f20a092cc2afe988822b35512d13f987a..6d50ed459dfb190a43ff0bf598135af9b616c899 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -4,13 +4,13 @@ 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: יצירת קשר
+    contact_missing: ללא הגדרה
     contact_unavailable: לא רלוונטי/חסר
-    description_headline: מהו %{domain}?
-    domain_count_after: שרתים אחרים
-    domain_count_before: מחובר אל
+    documentation: תיעוד
     extended_description_html: |
       <h3>מקום טוב לכללים</h3>
       <p>התיאור המורחב טרם הוגדר.</p>
@@ -44,7 +44,6 @@ he:
     people_who_follow: העוקבים של %{name}
     posts: הודעות
     posts_with_replies: חצרוצים ותגובות
-    remote_follow: מעקב מרחוק
     reserved_username: שם המשתמש שמור
     roles:
       admin: מנהל
@@ -96,10 +95,6 @@ he:
       most_recent_activity: פעילות עדכנית
       most_recent_ip: כתובות אחרונות
       not_subscribed: לא רשום
-      order:
-        alphabetic: אלפביתי
-        most_recent: עדכני
-        title: סידור
       outbox_url: כתובת תיבת דואר יוצא
       perform_full_suspension: ביצוע השעייה מלאה
       profile_url: כתובת פרופיל
@@ -125,7 +120,6 @@ he:
       shared_inbox_url: תיבה משותפת לדואר נכנס
       show:
         created_reports: דיווחים מאת חשבון זה
-        report: דו"ח
         targeted_reports: דיווחים נגד חשבון זה
       silence: השתקה
       statuses: הודעות
@@ -162,10 +156,6 @@ he:
         title: חסימת שרת חדשה
       reject_media: חסימת קבצי מדיה
       reject_media_hint: מסירה קבצי מדיה השמורים מקומית ומונעת מהורדת קבצים נוספים בעתיד. לא רלוונטי להשעיות
-      severities:
-        silence: השתקה
-        suspend: השעייה
-      severity: חוּמרה
       show:
         affected_accounts:
           one: חשבון אחד במסד הנתונים מושפע
@@ -175,30 +165,21 @@ he:
           suspend: הסרת השעייה מכל החשבונות על שרת זה
         title: ביטול חסימת שרת עבור %{domain}
         undo: ביטול
-      title: חסימת שרתים
       undo: ביטול
     instances:
-      account_count: חשבונות מוכרים
-      domain_name: שם מתחם
       title: שרתים מוכרים
     reports:
       are_you_sure: 100% על בטוח?
       comment:
         none: ללא
-      id: ID
       mark_as_resolved: סימון כפתור
       report: 'דווח על #%{id}'
-      report_contents: תוכן
       reported_account: חשבון מדווח
       reported_by: דווח על ידי
       resolved: פתור
-      silence_account: השתקת חשבון
       status: הודעה
-      suspend_account: השעיית חשבון
-      target: מטרה
       title: דיווחים
       unresolved: לא פתור
-      view: תצוגה
     settings:
       contact_information:
         email: נא להקליד כתובת דוא"ל פומבית
@@ -286,7 +267,6 @@ he:
     unlocked_warning_title: חשבונך אינו נעול
   generic:
     changes_saved_msg: השינויים נשמרו בהצלחה!
-    powered_by: רץ על %{link}
     save_changes: שמור שינויים
     validation_errors:
       one: משהו לא לגמרי בסדר עדיין! אנא הציצו על השגיאה מטה
@@ -299,15 +279,13 @@ he:
       following: רשימת נעקבים
       muting: רשימת השתקות
     upload: יבוא
-  landing_strip_html: "<strong>%{name}</strong> מזהה משתמש(ת) מהקהילה %{link_to_root_path}. ניתן לעקוב אחריהם או לדבר איתם בעזרת חשבון על כל שרת קהילה ברחבי הפדרציה."
-  landing_strip_signup_html: לחלופין , ניתן <a href="%{sign_up_path}">להרשם מקומית כאן</a>.
   media_attachments:
     validations:
       images_and_video: לא ניתן להוסיף וידאו לחצרוץ שכבר מכיל תמונות
       too_many: לא ניתן להוסיף יותר מארבעה קבצים
   notification_mailer:
     digest:
-      body: 'להלן סיכום זריז של הדברים שקרו על %{instance} מאז ביקורך האחרון ב-%{since}:'
+      body: להלן סיכום זריז של הדברים שקרו על מאז ביקורך האחרון ב-%{since}
       mention: "%{name} פנה אליך ב:"
       new_followers_summary:
         one: נוסף לך עוקב! סחתיין!
@@ -372,7 +350,6 @@ he:
       unlisted: מוסתר
       unlisted_long: פומבי, אבל לא להצגה בפיד הציבורי
   stream_entries:
-    click_to_show: ללחוץ להצגה
     reblogged: הודהד
     sensitive_content: תוכן רגיש
   time:
diff --git a/config/locales/hi.yml b/config/locales/hi.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93
--- /dev/null
+++ b/config/locales/hi.yml
@@ -0,0 +1 @@
+{}
diff --git a/config/locales/hr.yml b/config/locales/hr.yml
index 2d2eddc08c64bf5fe7d6de4dd4ba8f24bfc9ab40..38971833c1fd2ac9874d433609f01d6d1cd01b85 100644
--- a/config/locales/hr.yml
+++ b/config/locales/hr.yml
@@ -5,9 +5,6 @@ hr:
     about_this: O ovoj instanci
     closed_registrations: Registracije na ovoj instanci su trenutno zatvorene.
     contact: Kontakt
-    description_headline: Å to je %{domain}?
-    domain_count_after: druge instance
-    domain_count_before: Spojen na
     other_instances: Druge instance
     source_code: Izvorni kod
     status_count_after: statusi
@@ -22,7 +19,6 @@ hr:
     people_followed_by: Ljudi koje %{name} slijedi
     people_who_follow: Ljudi koji slijede %{name}
     posts: Postovi
-    remote_follow: Remote follow
     unfollow: Prestani slijediti
   application_mailer:
     settings: 'Promijeni e-mail postavke: %{link}'
@@ -64,11 +60,8 @@ hr:
     storage: Pohrana media zapisa
   generic:
     changes_saved_msg: Izmjene su uspješno sačuvane!
-    powered_by: omogućuje %{link}
     save_changes: Sačuvaj izmjene
-    validation_errors:
-      one: Nešto ne štima! Vidi grešku ispod
-      other: Nešto još uvijek ne štima! Vidi %{count} greške ispod
+    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
@@ -77,18 +70,12 @@ hr:
       following: Lista onih koje slijedim
       muting: Lista utišanih
     upload: Upload
-  landing_strip_html: "<strong>%{name}</strong> je korisnik na %{link_to_root_path}. Možeš ih slijediti ili komunicirati s njima ako imaš račun igdje u fediversu."
-  landing_strip_signup_html: Ako nemaš, možeš se <a href="%{sign_up_path}">registrirati ovdje</a>.
   notification_mailer:
     digest:
-      body: 'Ovo je kratak sažetak propuštenog %{instance} od tvog prošlog posjeta %{since}:'
+      body: Ovo je kratak sažetak propuštenog od tvog prošlog posjeta %{since}
       mention: "%{name} te je spomenuo:"
-      new_followers_summary:
-        one: Imaš novog sljedbenika! Yay!
-        other: Imaš %{count} novih sljedbenika! Prekrašno!
-      subject:
-        one: "1 nova notifikacija od tvog prošlog posjeta \U0001F418"
-        other: "%{count} novih notifikacija od tvog prošlog posjeta \U0001F418"
+      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"
@@ -141,7 +128,6 @@ hr:
       public: Javno
       unlisted: Javno, no nemoj prikazati na javnom timelineu
   stream_entries:
-    click_to_show: Klikni da bi prikazao
     reblogged: potaknut
     sensitive_content: Osjetljivi sadržaj
   time:
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index c0dcb438aa77a6ce29cd5c9ab404d50998483f49..d093815a8c72b73683a9ba8cf58275348e25f6ee 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -8,9 +8,6 @@ hu:
     contact: Kapcsolat
     contact_missing: Nincs megadva
     contact_unavailable: N/A
-    description_headline: Mi az a %{domain}?
-    domain_count_after: további instanciával
-    domain_count_before: Kapcsolatban
     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>
@@ -44,7 +41,6 @@ hu:
     people_who_follow: "%{name} követői"
     posts: Tülkök
     posts_with_replies: Tülkök és válaszok
-    remote_follow: Követés más hálózaton
     reserved_username: Ez egy már lefoglalt felhasználónév
     roles:
       admin: Adminisztrátor
@@ -96,10 +92,6 @@ hu:
       most_recent_activity: Legutóbbi tevékenységek
       most_recent_ip: Legutóbbi IP-cím
       not_subscribed: Nincs feliratkozás
-      order:
-        alphabetic: Alfabetikus
-        most_recent: Legutóbbi
-        title: Rendezés
       outbox_url: Kimenő üzenetek URL
       perform_full_suspension: Teljes felfüggesztés
       profile_url: Profil URL
@@ -126,7 +118,6 @@ hu:
       shared_inbox_url: Bejövő üzenetek URL keresése
       show:
         created_reports: Ezen fiók által létrehozott jelentések
-        report: jelentés
         targeted_reports: Jelentések ezzel a fiókkal kapcsolatban
       silence: Némítás
       statuses: Tülkök
@@ -204,11 +195,6 @@ hu:
         title: Új domain-tiltás
       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ó
-      severities:
-        noop: Egyik sem
-        silence: Némítás
-        suspend: Felfüggesztés
-      severity: Súlyosság
       show:
         affected_accounts:
           one: Összesen egy fiók érintett az adatbázisban
@@ -218,7 +204,6 @@ 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
-      title: Tiltott domainek
       undo: Visszavonás
     email_domain_blocks:
       add_new: Új hozzáadása
@@ -231,10 +216,6 @@ hu:
         title: Új e-mail feketelista bejegyzés
       title: E-mail feketelista
     instances:
-      account_count: Nyilvántartott fiókok
-      domain_name: Domain
-      reset: Visszaállítás
-      search: Keresés
       title: Nyilvántartott instanciák
     invites:
       filter:
@@ -248,20 +229,14 @@ hu:
       are_you_sure: Biztos vagy benne?
       comment:
         none: Egyik sem
-      id: ID
       mark_as_resolved: Megjelölés megoldottként
       report: "#%{id} számú jelentés"
-      report_contents: Tartalom
       reported_account: Bejelentett fiók
       reported_by: 'Jelentette:'
       resolved: Megoldott
-      silence_account: Felhasználó némítása
       status: Állapot
-      suspend_account: Felhasználó felfüggesztése
-      target: Cél
       title: Jelentések
       unresolved: Megoldatlan
-      view: Megtekintés
     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
@@ -406,7 +381,7 @@ hu:
     '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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">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álod az egyik, a platformodnak megfelelő <a href="%{apps_path}">alkalmazást</a>.
   exports:
     blocks: Tiltólistádon
     csv: CSV
@@ -427,11 +402,10 @@ hu:
     unlocked_warning_title: A fiókod jelenleg nem privát
   generic:
     changes_saved_msg: Változások sikeresen elmentve!
-    powered_by: működteti a %{link}
     save_changes: Változások mentése
     validation_errors:
       one: Valami nincs rendjén! Kérlek tekintsd meg a hibát alant
-      other: Valami nincs rendjén! Kérlek tekintsd meg a %{count} darab hibát alant.
+      other: Valami nincs rendjén! Kérlek tekintsd meg a %{count} darab hibát alant
   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.
     success: Adataidat sikeresen feltöltöttük és feldolgozásukat megkezdtük
@@ -461,8 +435,6 @@ hu:
       expires_at: Lejárat
       uses: Használat
     title: Meghívások
-  landing_strip_html: "<strong>%{name}</strong> az alábbi instancia használója: %{link_to_root_path}. Követheted vagy kapcsolatba léphetsz vele, ha már van felhasználói fiókod a föderációban."
-  landing_strip_signup_html: Ha még nincs fiókod, <a href="%{sign_up_path}">itt regisztrálhatsz</a>.
   lists:
     errors:
       limit: Elérted a hozzáadható listák maximális számát
@@ -610,7 +582,6 @@ hu:
       unlisted: Listázatlan
       unlisted_long: Mindenki látja, de a nyilvános időfolyamokban nem jelenik meg
   stream_entries:
-    click_to_show: Megtekintéshez kattints
     pinned: Kitűzött tülk
     reblogged: reblogolt
     sensitive_content: Szenzitív tartalom
@@ -649,7 +620,6 @@ hu:
       review_preferences_action: Beállítások módosítása
       review_preferences_step: Tekintsd át beállításaidat, például hogy milyen értesítéseket kérsz emailben vagy hogy alapértelmezettként mi legyen a tülkjeid adatvédelmi beállítása. Ha nem vagy szédülős alkat, azt is engedélyezheted, hogy automatikusan lejátsszuk a GIF-eket.
       subject: Üdvözöl a Mastodon
-      tip_bridge_html: Ha a Twitterről érkezel, használhatod <a href="%{bridge_url}">alkalmazásunkat</a>, amellyel megtalálhatod Twitteres barátaidat a Mastodonon. Az alkalmazás csak azon barátaidat tudja megtalálni, akik maguk is használták azt!
       tip_federated_timeline: A nyilvános időfolyam a Mastodon ütőere, ahol minden tülk összefolyik. Nem teljes ugyan, mert csak azokat az emberek fogod látni, akiket instanciád többi felhasználója követ.
       tip_following: Alapértelmezettként instanciád adminisztrátorait követed. Látogasd meg a helyi és a nyilvános időfolyamot, hogy más érdekes emberekre is rátalálj.
       tip_local_timeline: A helyi időfolyam a saját instanciád (%{instance}) ütőere. Ezek a kedves emberek itt mind a szomszédaid!
diff --git a/config/locales/id.yml b/config/locales/id.yml
index 4fb75f2b0e5fa56f1d3262d30192337693049983..fabf2746e396661134fe2a9abf07092359ea0077 100644
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -1,30 +1,75 @@
 ---
 id:
   about:
+    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
-    closed_registrations: Pendaftaran untuk server ini sedang ditutup.
+    api: API
+    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
-    description_headline: Apa itu %{domain}?
-    domain_count_after: server lain
-    domain_count_before: Terhubung dengan
-    other_instances: Server lain
+    contact_missing: Belum diset
+    contact_unavailable: Tidak Tersedia
+    documentation: Dokumentasi
+    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: status
+    status_count_after:
+      one: status
+      other: status
     status_count_before: Yang telah menulis
-    user_count_after: pengguna
+    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: Pengikut
-    following: Mengikut
+    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!
     people_followed_by: Orang yang diikuti %{name}
     people_who_follow: Orang-orang yang mengikuti %{name}
-    posts: Postingan
-    remote_follow: Mengikuti
+    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
     accounts:
       are_you_sure: Anda yakin?
       confirm: Konfirmasi
@@ -52,10 +97,6 @@ id:
       most_recent_activity: Aktivitas terbaru
       most_recent_ip: IP terbaru
       not_subscribed: Tidak berlangganan
-      order:
-        alphabetic: Alfabetik
-        most_recent: Terbaru
-        title: Urutan
       perform_full_suspension: Lakukan suspen penuh
       profile_url: URL profil
       public: Publik
@@ -68,7 +109,6 @@ id:
       salmon_url: URL Salmon
       show:
         created_reports: Laporan yang dibuat oleh akun ini
-        report: laporan
         targeted_reports: Laporan yang dibuat tentang akun ini
       silence: Diam
       statuses: Status
@@ -92,10 +132,6 @@ id:
         title: Pemblokiran domain baru
       reject_media: Tolak berkas media
       reject_media_hint: Hapus file media yang tersimpan dan menolak semua unduhan nantinya. Tidak terpengaruh dengan suspen
-      severities:
-        silence: Diamkan
-        suspend: Suspen
-      severity: Keparahan
       show:
         affected_accounts:
           one: Satu akun di dalam database terpengaruh
@@ -105,28 +141,19 @@ id:
           suspend: Hapus suspen terhadap akun pada domain ini
         title: Hapus pemblokiran domain %{domain}
         undo: Undo
-      title: Pemblokiran Domain
     instances:
-      account_count: Akun yang diketahui
-      domain_name: Domain
       title: Server yang diketahui
     reports:
       comment:
         none: Tidak ada
-      id: ID
       mark_as_resolved: Tandai telah diseleseikan
       report: 'Laporkan #%{id}'
-      report_contents: Konten
       reported_account: Akun yang dilaporkan
       reported_by: Dilaporkan oleh
       resolved: Terseleseikan
-      silence_account: Akun yang didiamkan
       status: Status
-      suspend_account: Akun yang disuspen
-      target: Target
       title: Laporan
       unresolved: Belum Terseleseikan
-      view: Tampilan
     settings:
       contact_information:
         email: Masukkan alamat email
@@ -192,7 +219,7 @@ id:
     '410': Halaman yang anda cari sudah tidak dapat ditemukan lagi.
     '422':
       content: Verifikasi keamanan gagal. Apa anda memblokir cookie?
-      title: Verifikasi keamanan gagal.
+      title: Verifikasi keamanan gagal
   exports:
     blocks: Anda blokir
     csv: CSV
@@ -213,11 +240,8 @@ id:
     unlocked_warning_title: Akun anda tidak dikunci
   generic:
     changes_saved_msg: Perubahan berhasil disimpan!
-    powered_by: didukung oleh %{link}
     save_changes: Simpan perubahan
-    validation_errors:
-      one: Ada yang tidak beres! Mohon tinjau error dibawah ini
-      other: Ada yang tidak beres! Mohon tinjau error dibawah ini
+    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
@@ -226,15 +250,13 @@ id:
       following: Daftar diikuti
       muting: Daftar didiamkan
     upload: Unggah
-  landing_strip_html: "<strong>%{name}</strong> adalah pengguna di %{link_to_root_path}.Anda dapat mengikuti mereka atau berinteraksi dengan mereka jika anda memiliki akun di fediverse."
-  landing_strip_signup_html: Jika anda tidak punya, anda bisa <a href="%{sign_up_path}">daftar disini</a>.
   media_attachments:
     validations:
       images_and_video: Tidak bisa melampirkan video pada status yang telah memiliki gambar
       too_many: Tidak dapat melampirkan lebih dari 4 file
   notification_mailer:
     digest:
-      body: 'Ini adalah ringkasan singkat yang anda lewatkan pada %{instance} sejak kunjungan terakhir anda pada %{since}:'
+      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!
@@ -298,7 +320,6 @@ id:
       public_long: Bisa dilihat semua orang
       unlisted: Bisa dilihat semua orang, tapi tidak ditampilkan di linimasa publik
   stream_entries:
-    click_to_show: Klik untuk menampilkan
     reblogged: di-boost-kan
     sensitive_content: Konten sensitif
   time:
diff --git a/config/locales/io.yml b/config/locales/io.yml
index bf15de4886ab43227f1744bb4a567e512a956e97..73c981a985a9971a392146ec32bdfb2af0a4ba5d 100644
--- a/config/locales/io.yml
+++ b/config/locales/io.yml
@@ -5,9 +5,6 @@ io:
     about_this: Pri ta instaluro
     closed_registrations: Membresko ne nun esas posible en ta instaluro.
     contact: Kontaktar
-    description_headline: Quo esas %{domain}?
-    domain_count_after: altra instaluri
-    domain_count_before: Konektita ad
     other_instances: Altra instaluri
     source_code: Fontkodexo
     status_count_after: mesaji
@@ -22,7 +19,6 @@ io:
     people_followed_by: Sequati da %{name}
     people_who_follow: Sequanti di %{name}
     posts: Mesaji
-    remote_follow: Fore sequar
     unfollow: Dessequar
   admin:
     accounts:
@@ -48,10 +44,6 @@ io:
       most_recent_activity: Most recent activity
       most_recent_ip: Most recent IP
       not_subscribed: Not subscribed
-      order:
-        alphabetic: Alphabetic
-        most_recent: Most recent
-        title: Order
       perform_full_suspension: Perform full suspension
       profile_url: Profile URL
       public: Public
@@ -60,7 +52,6 @@ io:
       salmon_url: Salmon URL
       show:
         created_reports: Reports created by this account
-        report: report
         targeted_reports: Reports made about this account
       silence: Silence
       statuses: Statuses
@@ -84,10 +75,6 @@ io:
         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
-      severities:
-        silence: Silence
-        suspend: Suspend
-      severity: Severity
       show:
         affected_accounts:
           one: One account in the database affected
@@ -97,28 +84,20 @@ io:
           suspend: Unsuspend all existing accounts from this domain
         title: Undo domain block for %{domain}
         undo: Undo
-      title: Domain Blocks
       undo: Undo
     instances:
-      account_count: Known accounts
-      domain_name: Domain
       title: Known Instances
     reports:
       comment:
         none: None
-      id: ID
       mark_as_resolved: Mark as resolved
       report: 'Report #%{id}'
       reported_account: Reported account
       reported_by: Reported by
       resolved: Resolved
-      silence_account: Silence account
       status: Status
-      suspend_account: Suspend account
-      target: Target
       title: Reports
       unresolved: Unresolved
-      view: View
     settings:
       contact_information:
         email: Enter a public e-mail address
@@ -192,28 +171,25 @@ io:
     storage: Konservado di kontenajo
   generic:
     changes_saved_msg: Chanji senprobleme konservita!
-    powered_by: povigita da %{link}
     save_changes: Konservar la chanji
     validation_errors:
-      one: Ulo ne eventis senprobleme! Voluntez konsultar la suba eror-raporto.
-      other: Ulo ne eventis senprobleme! Voluntez konsultar la suba %{count} eror-raporti.
+      one: Ulo ne eventis senprobleme! Voluntez konsultar la suba eror-raporto
+      other: Ulo ne eventis senprobleme! Voluntez konsultar la suba %{count} eror-raporti
   imports:
     preface: Tu povas importacar kelka datumi, tal quala listi de omna homi quin tu sequas o blokusas, a tua konto di ca instaluro, per dosiero exportacita de altra instaluro.
-    success: Tua datumi esis senprobleme importacita ed esos traktita quale projetita.
+    success: Tua datumi esis senprobleme importacita ed esos traktita quale projetita
     types:
       blocking: Listo de blokusiti
       following: Listo de sequati
       muting: Muting list
     upload: Kargar
-  landing_strip_html: "<strong>%{name}</strong> esas uzero en %{link_to_root_path}. Tu povas sequar lu o komunikar kun lu, se tu havas konto irgaloke en la Fediverse."
-  landing_strip_signup_html: Se tu ne havas, tu povas <a href="%{sign_up_path}">membreskar hike</a>.
   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
   notification_mailer:
     digest:
-      body: 'Yen mikra rezumo di to, quo eventis en %{instance}, depos ke tu laste vizitis en %{since}:'
+      body: Yen mikra rezumo di to, depos ke tu laste vizitis en %{since}
       mention: "%{name} mencionis tu en:"
       new_followers_summary:
         one: Tu obtenis nova sequanto! Yey!
@@ -274,7 +250,6 @@ io:
       public: Publika
       unlisted: Publika, ma ne aperos en publika tempolinei
   stream_entries:
-    click_to_show: Kliktar por montrar
     reblogged: diskonocigita
     sensitive_content: Titiliva kontenajo
   time:
diff --git a/config/locales/it.yml b/config/locales/it.yml
index 31dffd5a9995ef18786cd0a5fdb82fc90a5882a8..6d45ece8356c1bdff059d0c7c339580c7297f6e5 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -5,49 +5,64 @@ it:
     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
     administered_by: 'Amministrato da:'
-    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 di questa.
+    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.
     contact: Contatti
     contact_missing: Non impostato
     contact_unavailable: N/D
-    description_headline: Cos'è %{domain}?
-    domain_count_after: altri server
-    domain_count_before: Connesso a
+    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 di design etico per combattere l'abuso dei social media.
+      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 giardino murato. Non c'è nessuna autorità centrale.
+      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 ovunque al passo con i tuoi amici.
+      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
     generic_description: "%{domain} è un server nella rete"
     hosted_on: Mastodon ospitato su %{domain}
     learn_more: Scopri altro
     other_instances: Elenco istanze
+    privacy_policy: Policy su la Privacy
     source_code: Codice sorgente
-    status_count_after: stati
+    status_count_after:
+      one: status
+      other: status
     status_count_before: Che hanno pubblicato
-    user_count_after: utenti
+    terms: Termini di Servizio
+    user_count_after:
+      one: utente
+      other: utenti
     user_count_before: Home di
     what_is_mastodon: Che cos'è Mastodon?
   accounts:
+    choices_html: 'Suggerimenti da %{name}:'
     follow: Segui
-    followers: Seguaci
+    followers:
+      one: Seguace
+      other: Seguaci
     following: Segui
+    joined: Dal %{date}
+    link_verified_on: La proprietà di questo link è stata controllata il %{date}
     media: Media
     moved_html: "%{name} è stato spostato su %{new_profile_link}:"
     network_hidden: Questa informazione non e' disponibile
     nothing_here: Qui non c'è nulla!
     people_followed_by: Persone seguite da %{name}
     people_who_follow: Persone che seguono %{name}
-    posts: Posts
+    pin_errors:
+      following: Devi gia seguire la persona che vuoi promuovere
+    posts:
+      one: Toot
+      other: Toot
+    posts_tab_heading: Toot
     posts_with_replies: Toot e risposte
-    remote_follow: Segui da remoto
-    reserved_username: Il nome utente è riservato
+    reserved_username: Il nome utente è gia stato preso
     roles:
       admin: Amministratore
       bot: Bot
@@ -106,13 +121,10 @@ it:
       moderation_notes: Note di moderazione
       most_recent_activity: Attività più recenti
       most_recent_ip: IP più recenti
+      no_limits_imposed: Nessun limite imposto
       not_subscribed: Non sottoscritto
-      order:
-        alphabetic: Alfabetico
-        most_recent: Più recente
-        title: Ordine
       outbox_url: URL outbox
-      perform_full_suspension: Esegui sospensione completa
+      perform_full_suspension: Sospendi
       profile_url: URL profilo
       promote: Promuovi
       protocol: Protocollo
@@ -138,11 +150,12 @@ it:
       shared_inbox_url: URL Inbox Condiviso
       show:
         created_reports: Rapporti creati da questo account
-        report: segnala
         targeted_reports: Rapporti che riguardano questo account
       silence: Silenzia
+      silenced: Silenziato
       statuses: Stati
       subscribe: Sottoscrivi
+      suspended: Sospeso
       title: Account
       unconfirmed_email: Email non confermata
       undo_silenced: Rimuovi silenzia
@@ -158,6 +171,8 @@ it:
         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"
+        demote_user: "%{name} ha degradato l'utente %{target}"
+        destroy_custom_emoji: "%{name} ha distrutto l'emoji %{target}"
         destroy_domain_block: "%{name} ha sbloccato il dominio %{target}"
         destroy_email_domain_block: "%{name}ha messo il dominio email %{target} nella whitelist"
         destroy_status: "%{name} ha eliminato lo status di %{target}"
@@ -174,9 +189,13 @@ it:
         resolve_report: "%{name} ha risolto il rapporto %{target}"
         silence_account: "%{name} ha silenziato l'account di %{target}"
         suspend_account: "%{name} ha sospeso l'account di %{target}"
+        unassigned_report: "%{name} report non assegnato %{target}"
         unsilence_account: "%{name} ha de-silenziato l'account di %{target}"
         unsuspend_account: "%{name} ha annullato la sospensione dell'account di %{target}"
         update_custom_emoji: "%{name} ha aggiornato l'emoji %{target}"
+        update_status: "%{name} stato aggiornato da %{target}"
+      deleted_status: "(stato cancellato)"
+      title: Audit log
     custom_emojis:
       by_domain: Dominio
       copied_msg: Creata con successo una copia locale dell'emoji
@@ -202,6 +221,27 @@ it:
       update_failed_msg: Impossibile aggiornare questa emojii
       updated_msg: Emoji aggiornata con successo!
       upload: Carica
+    dashboard:
+      backlog: backlogged jobs
+      config: Configurazione
+      feature_deletions: Cancellazioni di account
+      feature_invites: Link di invito
+      feature_registrations: Registrazioni
+      feature_relay: Ripetitore di federazione
+      features: Funzionalità
+      hidden_service: Federazione con servizi nascosti
+      open_reports: apri report
+      recent_users: Utenti Recenti
+      search: Ricerca testo intero
+      single_user_mode: Modalita utente singolo
+      software: Software
+      space: Utilizzo dello spazio
+      title: Dashboard
+      total_users: utenti totali
+      trends: Tendenze
+      week_interactions: interazioni per questa settimana
+      week_users_active: attivi questa settimana
+      week_users_new: utenti questa settimana
     domain_blocks:
       add_new: Aggiungi nuovo
       created_msg: Il blocco del dominio sta venendo processato
@@ -209,16 +249,17 @@ it:
       domain: Dominio
       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.
         severity:
+          desc_html: "<strong>Silenzia</strong> rende i post di questo account invisibili a chiunque non lo stia seguendo. <strong>Sospendi</strong> elimina tutti i contenuti, media e dati del profilo dell'account. Usa <strong>Nessuno</strong> se vuoi solo bloccare i file media."
           noop: Nessuno
           silence: Silenzia
           suspend: Sospendi
         title: Nuovo blocco dominio
-      severities:
-        noop: Nessuno
-        silence: Silenzia
-        suspend: Sospendi
-      severity: Severità
+      reject_media: Rifiuta file media
+      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
       show:
         affected_accounts:
           one: Interessato un solo account nel database
@@ -228,7 +269,6 @@ it:
           suspend: Annulla la sospensione di tutti gli account esistenti da questo dominio
         title: Annulla il blocco del dominio per %{domain}
         undo: Annulla
-      title: Blocchi dominio
       undo: Annulla
     email_domain_blocks:
       add_new: Aggiungi nuovo
@@ -238,29 +278,47 @@ it:
       domain: Dominio
       new:
         create: Aggiungi dominio
+        title: Nuova voce della lista nera delle email
+      title: Lista nera email
     instances:
-      account_count: Accounts conosciuti
-      domain_name: Dominio
-      reset: Reimposta
-      search: Cerca
       title: Istanze conosciute
     invites:
+      deactivate_all: Disattiva tutto
       filter:
         all: Tutto
         available: Disponibile
         expired: Scaduto
         title: Filtro
       title: Inviti
+    relays:
+      add_new: Aggiungi ripetitore
+      delete: Cancella
+      description_html: Un <strong>ripetitore di federazione</strong> è un server che fa da intermediario e scambia grandi quantità di toot pubblici tra server che si collegano e pubblicano su di esso. <strong>Può aiutare server piccoli e medi a ottenere contenuti dal fediverse</strong>, che altrimenti riceverebbero solo se i loro utenti locali seguissero altre persone su server remoti.
+      disable: Disabilita
+      disabled: Disabilitato
+      enable: Abilita
+      enable_hint: Dopo l'attivazione, il vostro server riceverà tutti i toot pubblici da questo ripetitore, e inizierà a inviargli i suoi toot pubblici.
+      enabled: Abilitato
+      inbox_url: Url Relay
+      pending: In attesa dell'approvazione del ripetitore
+      save_and_enable: Salva e attiva
+      setup: Crea una connessione con un ripetitore
+      status: Status
+      title: Ripetitori
+    report_notes:
+      created_msg: Nota rapporto creata!
+      destroyed_msg: Nota rapporto cancellata!
     reports:
       account:
         note: note
+        report: rapporto
       action_taken_by: Azione intrapresa da
       are_you_sure: Sei sicuro?
       assign_to_self: Assegna a me
       assigned: Moderatore assegnato
       comment:
         none: Nessuno
-      id: ID
+      created_at: Segnalato
       mark_as_resolved: Segna come risolto
       mark_as_unresolved: Segna come non risolto
       notes:
@@ -268,30 +326,42 @@ it:
         create_and_resolve: Risolvi con nota
         create_and_unresolve: Riapri con nota
         delete: Elimina
+        placeholder: Descrivi quali azioni sono state intraprese, o ogni altro aggiornamento rilevante...
       reopen: Riapri rapporto
       report: 'Rapporto #%{id}'
-      report_contents: Contenuti
+      reported_account: Account segnalato
       reported_by: Inviato da
       resolved: Risolto
-      silence_account: Silenzia account
+      resolved_msg: Rapporto risolto!
       status: Stato
-      suspend_account: Sospendi account
-      target: Obbiettivo
+      title: Rapporti
       unassign: Non assegnare
       unresolved: Non risolto
       updated_at: Aggiornato
-      view: Mostra
     settings:
       activity_api_enabled:
         desc_html: Conteggi degli status pubblicati localmente, degli utenti attivi e delle nuove registrazioni in gruppi settimanali
         title: Pubblica statistiche aggregate circa l'attività dell'utente
       bootstrap_timeline_accounts:
+        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:
         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
+        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
+      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
       registrations:
         closed_message:
           desc_html: Mostrato nella pagina iniziale quando le registrazioni sono chiuse. Puoi usare tag HTML
@@ -311,11 +381,23 @@ it:
       show_staff_badge:
         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
+      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
+        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
       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
+      thumbnail:
+        desc_html: Usato per anteprime tramite OpenGraph e API. 1200x630px consigliati
+        title: Thumbnail dell'istanza
       timeline_preview:
+        desc_html: Mostra la timeline pubblica sulla pagina iniziale
         title: Anteprima timeline
       title: Impostazioni sito
     statuses:
@@ -328,6 +410,7 @@ it:
       media:
         title: Media
       no_media: Nessun media
+      no_status_selected: Nessun status è stato modificato perché nessuno era stato selezionato
       title: Gli status dell'account
       with_media: con media
     subscriptions:
@@ -359,7 +442,7 @@ it:
     didnt_get_confirmation: Non hai ricevuto le istruzioni di conferma?
     forgot_password: Hai dimenticato la tua password?
     login: Entra
-    logout: Sloggati
+    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
@@ -379,6 +462,7 @@ it:
     post_follow:
       close: Oppure puoi chiudere questa finestra.
       return: Mostra il profilo dell'utente
+      web: Vai al web
     title: Segui %{acct}
   datetime:
     distance_in_words:
@@ -408,7 +492,10 @@ it:
     '422':
       content: Verifica di sicurezza non riuscita. Stai bloccando i cookies?
       title: Verifica di sicurezza non riuscita
-    noscript_html: Per usare l'interfaccia web di Mastodon dovi abilitare JavaScript. In alternativa puoi provare una delle <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">app native</a> per Mastodon per la tua piattaforma.
+    '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.
   exports:
     archive_takeout:
       date: Data
@@ -422,16 +509,36 @@ it:
     follows: Stai seguendo
     mutes: Stai silenziando
     storage: Archiviazione media
+  filters:
+    contexts:
+      home: Timeline home
+      notifications: Notifiche
+      public: Timeline pubbliche
+      thread: Conversazioni
+    edit:
+      title: Modifica filtro
+    errors:
+      invalid_context: Contesto mancante o non valido
+    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…
   generic:
     changes_saved_msg: Modifiche effettuate con successo!
-    powered_by: offerto da %{link}
+    copy: Copia
     save_changes: Salva modifiche
     validation_errors:
       one: Qualcosa ancora non va bene! Per favore, controlla l'errore qui sotto
@@ -457,7 +564,9 @@ it:
       '86400': 1 giorno
     expires_in_prompt: Mai
     generate: Genera
+    invited_by: 'Sei stato invitato da:'
     max_uses:
+      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
@@ -465,8 +574,6 @@ it:
       expires_at: Scade
       uses: Utilizzi
     title: Invita persone
-  landing_strip_html: "<strong>%{name}</strong> è un utente su %{link_to_root_path}. Puoi seguirlo o interagire con lui se possiedi un account ovunque nel fediverse."
-  landing_strip_signup_html: Se non possiedi un account, puoi <a href="%{sign_up_path}">iscriverti qui</a>.
   lists:
     errors:
       limit: Hai raggiunto il numero massimo di liste
@@ -540,6 +647,7 @@ it:
   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:'
   remote_unfollow:
@@ -551,12 +659,29 @@ it:
     browsers:
       blackberry: Blackberry
       chrome: Chrome
+      edge: Microsoft Edge
+      firefox: Firefox
       generic: Browser sconosciuto
+      ie: Internet Explorer
+      opera: Opera
+      safari: Safari
     current_session: Sessione corrente
     description: "%{browser} su %{platform}"
     explanation: Questi sono i browser da cui attualmente è avvenuto l'accesso al tuo account 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: piattaforma sconosciuta
+      windows: Windows
+      windows_mobile: Windows Mobile
+      windows_phone: Windows Phone
     title: Sessioni
   settings:
     authorized_apps: Applicazioni autorizzate
@@ -595,6 +720,7 @@ it:
       private: Un toot non pubblico non può essere fissato in cima
       reblog: Un toot condiviso non può essere fissato in cima
     show_more: Mostra di più
+    sign_in_to_participate: Accedi per partecipare alla conversazione
     visibilities:
       private: Mostra solo ai tuoi seguaci
       private_long: Mostra solo ai seguaci
@@ -603,7 +729,6 @@ it:
       unlisted: Pubblico, ma non visibile sulla timeline pubblica
       unlisted_long: Tutti lo possono vedere, ma non compare nelle timeline pubbliche
   stream_entries:
-    click_to_show: Clicca per mostrare
     pinned: Toot fissato in cima
     reblogged: condiviso
     sensitive_content: Materiale sensibile
@@ -612,6 +737,7 @@ it:
   themes:
     contrast: Contrasto elevato
     default: Mastodon
+    mastodon-light: Mastodon (chiaro)
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
@@ -626,10 +752,11 @@ it:
     instructions_html: "<strong>Scannerizza questo QR code con Google Authenticator o un'app TOTP simile sul tuo telefono</strong>. Da ora in poi, quell'applicazione genererà codici da inserire necessariamente per eseguire l'accesso."
     lost_recovery_codes: I codici di recupero ti permettono di accedere al tuo account se perdi il telefono. Se hai perso i tuoi codici di recupero, puoi rigenerarli qui. Quelli vecchi saranno annullati.
     manual_instructions: 'Se non puoi scannerizzare il QR code e hai bisogno di inserirlo manualmente, questo è il codice segreto in chiaro:'
+    recovery_codes: Codici di recupero del backup
     recovery_codes_regenerated: I codici di recupero sono stati rigenerati
     recovery_instructions_html: Se perdi il telefono, puoi usare uno dei codici di recupero qui sotto per riottenere l'accesso al tuo account. <strong>Conserva i codici di recupero in un posto sicuro</strong>. Ad esempio puoi stamparli e conservarli insieme ad altri documenti importanti.
     setup: Configura
-    wrong_code: Il codice inserito non è corretto! Assicurati che l'orario del server e l'orario del dispotivo siano corretti.
+    wrong_code: Il codice inserito non è corretto! Assicurati che l'orario del server e l'orario del dispositivo siano corretti.
   user_mailer:
     backup_ready:
       explanation: Hai richiesto un backup completo del tuo account Mastodon. È pronto per essere scaricato!
@@ -645,7 +772,6 @@ it:
       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
-      tip_bridge_html: Se vieni da Twitter, puoi trovare i tuoi amici su Mastodon usando la<a href="%{bridge_url}">app bridge</a>. Ma funziona solo se anche loro la usano!
       tip_federated_timeline: La timeline federata visualizza uno dopo l'altro i messaggi pubblicati su Mastodon. Ma comprende solo gli utenti seguiti dai tuoi vicini, quindi non è completa.
       tip_following: Per impostazione predefinita, segui l'amministratore/i del tuo server. Per trovare utenti più interessanti, dà un'occhiata alle timeline locale e federata.
       tip_local_timeline: La timeline locale visualizza uno dopo l'altro i messaggi degli utenti di %{instance}. Questi sono i tuoi vicini!
@@ -653,6 +779,11 @@ it:
       tips: Suggerimenti
       title: Benvenuto a bordo, %{name}!
   users:
+    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
     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:
+    explanation_html: 'Puoi <strong>certificare te stesso come proprietario dei link nei metadati del tuo profilo</strong>. Per farlo, il sito a cui punta il link deve contenere un link che punta al tuo profilo Mastodon. Il link di ritorno <strong>deve</strong> avere l''attributo <code>rel="me"</code>. Il testo del link non ha importanza. Ecco un esempio:'
+    verification: Verifica
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 0e30a39e74c658f9560e6463fa45dd77cb3c4a40..7ccb2f21c52fb5a8d86c153261f14e3485ee346c 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -5,20 +5,20 @@ ja:
     about_mastodon_html: Mastodon は、オープンなウェブプロトコルを採用した、自由でオープンソースなソーシャルネットワークです。電子メールのような分散型の仕組みを採っています。
     about_this: 詳細情報
     administered_by: '管理者:'
+    api: API
+    apps: アプリ
     closed_registrations: 現在このインスタンスでの新規登録は受け付けていません。しかし、他のインスタンスにアカウントを作成しても全く同じネットワークに参加することができます。
     contact: 連絡先
     contact_missing: 未設定
     contact_unavailable: N/A
-    description_headline: "%{domain} とは?"
-    domain_count_after: 個のインスタンス
-    domain_count_before: 接続中
+    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_body: Mastodon は営利的な SNS ではありません。広告や、データの収集・解析によるターゲティングは無く、またユーザーの囲い込みもありません。ここには中央権力はありません。
       not_a_product_title: あなたは人間であり、商品ではありません
       real_conversation_body: 好きなように書ける500文字までの投稿や、文章やメディアの内容に警告をつけられる機能で、思い通りに自分自身を表現することができます。
       real_conversation_title: 本当のコミュニケーションのために
@@ -28,25 +28,41 @@ ja:
     hosted_on: Mastodon hosted on %{domain}
     learn_more: もっと詳しく
     other_instances: 他のインスタンス
+    privacy_policy: プライバシーポリシー
     source_code: ソースコード
-    status_count_after: トゥート
+    status_count_after:
+      one: トゥート
+      other: トゥート
     status_count_before: トゥート数
-    user_count_after: 人
+    terms: 利用規約
+    user_count_after:
+      one: 人
+      other: 人
     user_count_before: ユーザー数
     what_is_mastodon: Mastodon とは?
   accounts:
+    choices_html: "%{name} によるおすすめ:"
     follow: フォロー
-    followers: フォロワー
+    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} さんをフォロー中のアカウント"
-    posts: トゥート
+    pin_errors:
+      following: おすすめしたい人はあなたが既にフォローしている必要があります
+    posts:
+      one: トゥート
+      other: トゥート
+    posts_tab_heading: トゥート
     posts_with_replies: トゥートと返信
-    remote_follow: リモートフォロー
     reserved_username: このユーザー名は予約されています
     roles:
       admin: Admin
@@ -54,6 +70,9 @@ ja:
       moderator: Mod
     unfollow: フォロー解除
   admin:
+    account_actions:
+      action: アクションを実行
+      title: "%{acct}さんに対してアクションを実行"
     account_moderation_notes:
       create: 書き込む
       created_msg: モデレーションメモを書き込みました!
@@ -73,6 +92,7 @@ ja:
       confirm: 確認
       confirmed: 確認済み
       confirming: 確認中
+      deleted: 削除済み
       demote: 降格
       disable: 無効化
       disable_two_factor_authentication: 二段階認証を無効にする
@@ -88,8 +108,11 @@ ja:
       followers: フォロワー数
       followers_url: Followers URL
       follows: フォロー数
+      header: ヘッダー
       inbox_url: Inbox URL
+      invited_by: 招待した人
       ip: IP
+      joined: 登録日
       location:
         all: すべて
         local: ローカル
@@ -99,20 +122,18 @@ ja:
       media_attachments: 添付されたメディア
       memorialize: 追悼アカウント化
       moderation:
+        active: アクティブ
         all: すべて
-        silenced: サイレンス中
-        suspended: 停止中
+        silenced: サイレンス済み
+        suspended: 停止済み
         title: モデレーション
       moderation_notes: モデレーションメモ
       most_recent_activity: 直近の活動
       most_recent_ip: 直近のIP
+      no_limits_imposed: 制限なし
       not_subscribed: 購読していない
-      order:
-        alphabetic: アルファベット順
-        most_recent: 直近の活動順
-        title: 順序
       outbox_url: Outbox URL
-      perform_full_suspension: 完全に活動停止させる
+      perform_full_suspension: 活動を完全に停止させる
       profile_url: プロフィールURL
       promote: 昇格
       protocol: プロトコル
@@ -120,6 +141,7 @@ ja:
       push_subscription_expires: PuSH購読期限
       redownload: アバターの更新
       remove_avatar: アイコンを削除
+      remove_header: ヘッダーを削除
       resend_confirmation:
         already_confirmed: メールアドレスは確認済みです
         send: 確認メールを再送
@@ -135,30 +157,34 @@ ja:
         user: ユーザー
       salmon_url: Salmon URL
       search: 検索
-      shared_inbox_url: Shared Inbox URL
+      shared_inbox_url: Shared inbox URL
       show:
         created_reports: このアカウントで作られたレポート
-        report: レポート
         targeted_reports: このアカウントについてのレポート
       silence: サイレンス
+      silenced: サイレンス済み
       statuses: トゥート数
       subscribe: 購読する
+      suspended: 停止済み
       title: アカウント
       unconfirmed_email: 確認待ちのメールアドレス
       undo_silenced: サイレンスから戻す
       undo_suspension: 停止から戻す
       unsubscribe: 購読の解除
       username: ユーザー名
+      warn: 警告
       web: 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} さんの投稿を削除しました"
@@ -180,6 +206,7 @@ ja:
         unsuspend_account: "%{name} さんが %{target} さんの停止を解除しました"
         update_custom_emoji: "%{name} さんがカスタム絵文字 %{target} を更新しました"
         update_status: "%{name} さんが %{target} さんの投稿を更新しました"
+      deleted_status: "(削除済)"
       title: 操作履歴
     custom_emojis:
       by_domain: ドメイン
@@ -206,8 +233,30 @@ ja:
       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: 新規追加
+      add_new: ドメインブロックを追加
       created_msg: ドメインブロック処理を完了しました
       destroyed_msg: ドメインブロックを外しました
       domain: ドメイン
@@ -215,18 +264,20 @@ ja:
         create: ブロックを作成
         hint: ドメインブロックはデータベース中のアカウント項目の作成を妨げませんが、遡って自動的に指定されたモデレーションをそれらのアカウントに適用します。
         severity:
-          desc_html: "<strong>サイレンス</strong>はアカウントのトゥートをフォローしていない人から隠します。<strong>停止</strong>はそのアカウントのコンテンツ、メディア、プロフィールデータをすべて削除します。メディアファイルの拒否は<strong>なし</strong>を使います。"
+          desc_html: "<strong>サイレンス</strong>はアカウントのトゥートをフォローしていない人から隠します。<strong>停止</strong>はそのアカウントのコンテンツ、メディア、プロフィールデータをすべて削除します。メディアファイルを拒否したいだけの場合は<strong>なし</strong>を使います。"
           noop: なし
           silence: サイレンス
           suspend: 停止
         title: 新規ドメインブロック
       reject_media: メディアファイルを拒否
       reject_media_hint: ローカルに保存されたメディアファイルを削除し、今後のダウンロードを拒否します。停止とは無関係です
-      severities:
-        noop: なし
-        silence: サイレンス
-        suspend: 停止
-      severity: 深刻度
+      reject_reports: レポートを拒否
+      reject_reports_hint: このドメインからのレポートをすべて無視します。停止とは無関係です
+      rejecting_media: メディアファイルを拒否中
+      rejecting_reports: レポートを拒否中
+      severity:
+        silence: サイレンス中
+        suspend: 停止中
       show:
         affected_accounts:
           one: データベース中の一つのアカウントに影響します
@@ -236,7 +287,6 @@ ja:
           suspend: このドメインからの存在するすべてのアカウントの停止を戻す
         title: "%{domain}のドメインブロックを戻す"
         undo: 元に戻す
-      title: ドメインブロック
       undo: 元に戻す
     email_domain_blocks:
       add_new: 新規追加
@@ -248,19 +298,47 @@ ja:
         create: ドメインを追加
         title: メールアドレス用ブラックリスト新規追加
       title: メールブラックリスト
+    followers:
+      back_to_account: 戻る
+      title: "%{acct}さんのフォロワー"
     instances:
-      account_count: 既知のアカウント数
-      domain_name: ドメイン名
-      reset: リセット
-      search: 検索
+      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: "<strong>連合リレー</strong>とは、登録しているサーバー間の公開トゥートを仲介するサーバーです。<strong>中小規模のサーバーが連合のコンテンツを見つけるのを助けます。</strong>これを使用しない場合、ローカルユーザーがリモートユーザーを手動でフォローする必要があります。"
+      disable: 無効化
+      disabled: 無効
+      enable: 有効化
+      enable_hint: 有効にすると、リレーから全ての公開トゥートを受信するようになり、またこのサーバーの全ての公開トゥートをリレーに送信するようになります。
+      enabled: 有効
+      inbox_url: リレーURL
+      pending: リレーサーバーの承認待ちです
+      save_and_enable: 保存して有効にする
+      setup: リレー接続を設定する
+      status: ステータス
+      title: リレー
     report_notes:
       created_msg: レポートメモを書き込みました!
       destroyed_msg: レポートメモを削除しました!
@@ -275,7 +353,6 @@ ja:
       comment:
         none: なし
       created_at: レポート日時
-      id: ID
       mark_as_resolved: 解決済みとしてマーク
       mark_as_unresolved: 未解決として再び開く
       notes:
@@ -286,20 +363,15 @@ ja:
         placeholder: どのような措置が取られたか、または関連する更新を記述してください…
       reopen: 再び開く
       report: レポート#%{id}
-      report_contents: 内容
       reported_account: 報告対象アカウント
       reported_by: 報告者
       resolved: 解決済み
       resolved_msg: レポートを解決済みにしました!
-      silence_account: アカウントをサイレンス
       status: ステータス
-      suspend_account: アカウントを停止
-      target: ターゲット
       title: レポート
       unassign: 担当を外す
       unresolved: 未解決
       updated_at: 更新日時
-      view: 表示
     settings:
       activity_api_enabled:
         desc_html: 週ごとのローカルに投稿されたトゥート数、アクティブなユーザー数、新規登録者数
@@ -310,15 +382,24 @@ ja:
       contact_information:
         email: ビジネスメールアドレス
         username: 連絡先のユーザー名
+      custom_css:
+        desc_html: 全ページに適用されるCSSの編集
+        title: カスタムCSS
       hero:
-        desc_html: フロントページに表示されます。サイズは600x100px以上推奨です。未設定の場合、インスタンスのサムネイルが使用されます
+        desc_html: フロントページに表示されます。サイズは600x100px以上推奨です。未設定の場合、標準のサムネイルが使用されます
         title: ヒーローイメージ
+      mascot:
+        desc_html: 複数のページに表示されます。サイズは293x205px以上推奨です。未設定の場合、標準のマスコットが使用されます
+        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タグが使えます
@@ -339,11 +420,14 @@ ja:
         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: サイドバーと meta タグに表示されます。Mastodon とは何か、そしてこのサーバーの特別な何かを1段落で記述してください。空欄の場合、インスタンスの説明が使用されます。
+        title: 短いインスタンスの説明
       site_terms:
         desc_html: あなたは独自のプライバシーポリシーや利用規約、そのほかの法的根拠を書くことができます。HTMLタグが使えます
         title: カスタム利用規約
@@ -365,6 +449,7 @@ ja:
       media:
         title: メディア
       no_media: メディアなし
+      no_status_selected: 何も選択されていないため、変更されていません
       title: トゥート一覧
       with_media: メディアあり
     subscriptions:
@@ -374,7 +459,21 @@ ja:
       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_report:
       body: "%{reporter} が %{target} を通報しました"
@@ -396,7 +495,7 @@ ja:
     warning: このデータは気をつけて取り扱ってください。他の人と共有しないでください!
     your_token: アクセストークン
   auth:
-    agreement_html: 登録すると <a href="%{rules_path}">インスタンスのルール</a> と <a href="%{terms_path}">プライバシーポリシー</a> に従うことに同意したことになります。
+    agreement_html: 登録するをクリックすると <a href="%{rules_path}">インスタンスのルール</a> と <a href="%{terms_path}">プライバシーポリシー</a> に従うことに同意したことになります。
     change_password: パスワード
     confirm_email: メールアドレスの確認
     delete_account: アカウントの削除
@@ -452,6 +551,16 @@ ja:
     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': お探しのページは見つかりませんでした。
@@ -463,7 +572,7 @@ ja:
     '500':
       content: もうしわけありませんが、なにかが間違っています。
       title: このページは正しくありません
-    noscript_html: Mastodonのウェブアプリケーションを利用する場合はJavaScriptを有効にしてください。またはあなたのプラットフォーム向けの<a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">Mastodonネイティブアプリ</a>を探すことができます。
+    noscript_html: Mastodonのウェブアプリケーションを利用する場合はJavaScriptを有効にしてください。またはあなたのプラットフォーム向けの<a href="%{apps_path}">Mastodonネイティブアプリ</a>を探すことができます。
   exports:
     archive_takeout:
       date: 日時
@@ -474,7 +583,9 @@ ja:
       size: 容量
     blocks: ブロック
     csv: CSV
+    domain_blocks: 非表示にしたドメイン
     follows: フォロー
+    lists: リスト
     mutes: ミュート
     storage: メディア
   filters:
@@ -505,9 +616,13 @@ ja:
     true_privacy_html: "<strong>プライバシーの保護はエンドツーエンドの暗号化でのみ実現可能</strong>であることに留意ください。"
     unlocked_warning_html: 誰でもあなたをフォローすることができ、フォロワー限定の投稿をすぐに見ることができます。フォローする人を限定したい場合は%{lock_link}に設定してください。
     unlocked_warning_title: このアカウントは承認制アカウントに設定されていません
+  footer:
+    developers: 開発者向け
+    more: さらに…
+    resources: リソース
   generic:
     changes_saved_msg: 正常に変更されました!
-    powered_by: powered by %{link}
+    copy: コピー
     save_changes: 変更を保存
     validation_errors:
       one: エラーが発生しました! 以下のエラーを確認してください
@@ -543,8 +658,6 @@ ja:
       expires_at: 有効期限
       uses: 使用
     title: 新規ユーザーの招待
-  landing_strip_html: "<strong>%{name}</strong> さんはインスタンス %{link_to_root_path} のユーザーです。アカウントさえ持っていればフォローしたり会話したりできます。"
-  landing_strip_signup_html: もしお持ちでないなら <a href="%{sign_up_path}">こちら</a> からサインアップできます。
   lists:
     errors:
       limit: リストの上限に達しました
@@ -603,7 +716,6 @@ ja:
           quadrillion: Q
           thousand: K
           trillion: T
-          unit: ''
   pagination:
     newer: 新しいトゥート
     next: 次
@@ -621,10 +733,25 @@ ja:
     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: ブラウザ
@@ -695,7 +822,7 @@ ja:
     disallowed_hashtags:
       one: '許可されていないハッシュタグが含まれています: %{tags}'
       other: '許可されていないハッシュタグが含まれています: %{tags}'
-    language_detection: 自動的に言語を検出する
+    language_detection: 自動検出
     open_in_web: Webで開く
     over_character_limit: 上限は %{max}文字までです
     pin_errors:
@@ -704,6 +831,7 @@ ja:
       private: 非公開のトゥートを固定することはできません
       reblog: ブーストされたトゥートを固定することはできません
     show_more: もっと見る
+    sign_in_to_participate: ログインして会話に参加
     title: '%{name}: "%{quote}"'
     visibilities:
       private: フォロワー限定
@@ -713,7 +841,6 @@ ja:
       unlisted: 未収載
       unlisted_long: 誰でも見ることができますが、公開タイムラインには表示されません
   stream_entries:
-    click_to_show: クリックして表示
     pinned: 固定されたトゥート
     reblogged: さんがブースト
     sensitive_content: 閲覧注意
@@ -807,6 +934,7 @@ ja:
   time:
     formats:
       default: "%Y年%m月%d日 %H:%M"
+      month: "%Yå¹´ %b"
   two_factor_authentication:
     code_hint: 確認するには認証アプリで表示されたコードを入力してください
     description_html: "<strong>二段階認証</strong>を有効にするとログイン時、認証アプリからコードを入力する必要があります。"
@@ -822,12 +950,28 @@ ja:
     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: アバター画像やヘッダー画像をアップロードしたり、表示名やその他プロフィールを変更しカスタマイズすることができます。新しいフォロワーからのフォローを許可する前に検討したい場合、アカウントを承認制にすることができます。
@@ -839,7 +983,6 @@ ja:
       review_preferences_action: 設定の変更
       review_preferences_step: 受け取りたいメールや投稿の公開範囲などの設定を必ず行ってください。不快でないならアニメーション GIF の自動再生を有効にすることもできます。
       subject: Mastodon へようこそ
-      tip_bridge_html: もし Twitter から来られたのであれば、<a href="%{bridge_url}">bridge app</a> を使用することで Mastodon での友達のアカウントを探すこともできます。ただし bridge app を使用したことのある相手に限ります!
       tip_federated_timeline: 連合タイムラインは Mastodon ネットワークの流れを見られるものです。ただしあなたと同じインスタンスの人がフォローしている人だけが含まれるので、それが全てではありません。
       tip_following: 標準では自動でインスタンスの管理者をフォローしています。もっと興味のある人たちを見つけるには、ローカルタイムラインと連合タイムラインを確認してください。
       tip_local_timeline: ローカルタイムラインは %{instance} にいる人々の流れを見られるものです。彼らはあなたと同じインスタンスにいる隣人のようなものです!
@@ -847,8 +990,12 @@ ja:
       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プロフィールへのリンクが含まれている必要があります。リンクには<code>rel="me"</code>属性を<strong>必ず</strong>与えなければなりません。リンクのテキストについては重要ではありません。以下は例です:
+    verification: 認証
diff --git a/config/locales/ka.yml b/config/locales/ka.yml
new file mode 100644
index 0000000000000000000000000000000000000000..056942ecd5503a5cc876e727c930a68f60075995
--- /dev/null
+++ b/config/locales/ka.yml
@@ -0,0 +1,874 @@
+---
+ka:
+  about:
+    about_hashtag_html: ეს საჯარო ტუტებია, რომლებიც ატარებენ <strong>#%{hashtag}</strong> ტეგს. მათთან ინტერაქციას შეძლებთ, თუ ფედივერსში გაქვთ რაიმე ანგარიში.
+    about_mastodon_html: მასტოდონი ღია ვებ პროტოკოლებზე და უფასო, ღია პროგრამებზე დაფუძნებული სოციალური ქსელია. ის ისეთი დეცენტრალიზებულია როგორც ელ-ფოსტა.
+    about_this: შესახებ
+    administered_by: 'ადმინისტრატორი:'
+    api: აპი
+    apps: მობილური აპლიკაციები
+    closed_registrations: რეგისტრაციები ამჟამად ინსტანციაზე დახურულია. თუმცა! ანგარიშის შესაქმნელად შეგიძლიათ იპოვოთ სხვა ინსტანცია და იმავე ქსელზე იქონიოთ წვდომა იქიდან.
+    contact: კონტაქტი
+    contact_missing: არაა დაყენებული
+    contact_unavailable: მიუწ.
+    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: 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: მედია
+    moved_html: "%{name} გადავიდა %{new_profile_link}:"
+    network_hidden: ეს ინფორმაცია ხელმიუწვდომელია
+    nothing_here: აქ არაფერია!
+    people_followed_by: ხალხი ვისაც %{name} მიჰყვება
+    people_who_follow: ხალხი ვინც მიჰყვება %{name}-ს
+    pin_errors:
+      following: იმ ადამიანს, ვინც მოგწონთ, უკვე უნდა მიჰყვებოდეთ
+    posts: ტუტები
+    posts_with_replies: ტუტები და პასუხები
+    reserved_username: მომხმარებელი რეზერვირებულია
+    roles:
+      admin: ადმინისტრატორი
+      bot: ბოტი
+      moderator: მოდერატორი
+    unfollow: ნუღარ მიჰყვები
+  admin:
+    account_moderation_notes:
+      create: დატოვეთ ჩანაწერი
+      created_msg: მოდერაციის ჩანაწერი წარმატებით შეიქმნა!
+      delete: გაუქმება
+      destroyed_msg: მოდერაციის ჩანაწერი წარმატებით გაუქმდა!
+    accounts:
+      are_you_sure: დარწმუნებული ხარ?
+      avatar: ავატარი
+      by_domain: დომენი
+      change_email:
+        changed_msg: ანგარიშის ელ-ფოსტა წარმატებით შეიცვალა!
+        current_email: მიმდინარე ელ-ფოსტა
+        label: ელ-ფოსტის შეცვლა
+        new_email: ახალი ელ-ფოსტა
+        submit: ელ-ფოსტის შეცვლა
+        title: შეცვალეთ ელ-ფოსტა მომხმარებლისთვის %{username}
+      confirm: დადასტურება
+      confirmed: დადასტურებულია
+      confirming: დასტურდება
+      demote: დაქვეითება
+      disable: გამორთვა
+      disable_two_factor_authentication: გამორთე 2FA
+      disabled: გამორთულია
+      display_name: დისპლეი სახელი
+      domain: დომენი
+      edit: შეცვლა
+      email: ელ-ფოსტა
+      email_status: ელ-ფოსტის სტატუსი
+      enable: ჩართვა
+      enabled: ჩართულია
+      feed_url: ლენტის ურლ
+      followers: მიმდევრები
+      followers_url: მიმდევრების ურლ
+      follows: დადევნებები
+      inbox_url: ინბოქსის ურლ
+      ip: აი-პი
+      location:
+        all: ყველა
+        local: ლოკალური
+        remote: დისტანციური
+        title: ადგილმდებარეობა
+      login_status: ლოგინის სტატუსი
+      media_attachments: თან-დართული მედია
+      memorialize: აქციე მემორანდუმად
+      moderation:
+        all: ყველა
+        silenced: გაჩუმებული
+        suspended: შეჩერებული
+        title: მოდერაცია
+      moderation_notes: მოდერაციის ჩანაწერები
+      most_recent_activity: უახლესი აქტივობა
+      most_recent_ip: უახლესი აი-პი
+      not_subscribed: გამოუწერელი
+      outbox_url: აუთბოქსის ურლ
+      perform_full_suspension: მოახდინეთ სრული შეჩერება
+      profile_url: პროფილის ურლ
+      promote: დაწინაურება
+      protocol: პროტოკოლი
+      public: საჯარო
+      push_subscription_expires: ფუშ გამოწერა უქმდება
+      redownload: განაახლე ავატარი
+      remove_avatar: გააუქმე ავატარი
+      resend_confirmation:
+        already_confirmed: ეს მომხმარებელი უკვე დამოწმებულია
+        send: დამოწმების ინსტრუქციების გადაგზავნა
+        success: დამოწმების ინსტრუქციები წარმატებით გაიგზავნა!
+      reset: გადატვირთვა
+      reset_password: პაროლის გადატვირთვა
+      resubscribe: ხელახალი გამოწერა
+      role: უფლებები
+      roles:
+        admin: ადმინისტრატორი
+        moderator: მოდერატორი
+        staff: სტაფი
+        user: მომხმარებელი
+      salmon_url: სალმონის ურლ
+      search: ძებნა
+      shared_inbox_url: გაზიარებული ინბოქსის ურლ
+      show:
+        created_reports: ამ ანგარიშის მიერ შექმნილი რეპორტები
+        targeted_reports: ამ ანგარიშზე მიღებული რეპორტები
+      silence: სიჩუმე
+      statuses: სტატუსები
+      subscribe: გამოწერა
+      title: ანგარიშები
+      unconfirmed_email: დაუმოწმებელი ელ-ფოსტა
+      undo_silenced: გაჩუმების მოშორება
+      undo_suspension: შეჩერების მოშორება
+      unsubscribe: გამოწერის შეწყვეტა
+      username: მომხმარებლის სახელი
+      web: ვები
+    action_logs:
+      actions:
+        assigned_to_self_report: "%{name}-მა დანიშნა რეპორტი %{target} საკუთარ თავზე"
+        change_email_user: "%{name}-მა შეცვალა %{target} მომხმარებლის ელ-ფოსტის მისამართი"
+        confirm_user: "%{name}-მა დაამოწმა %{target} მომხმარებლის ელ-ფოსტის მისამართი"
+        create_custom_emoji: "%{name}-მა ატვირთა ახალი ემოჯი %{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} თეთრ სიაში მოაქცია დომენი %{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 50კბმდე
+      listed: ჩამოთვლილი
+      new:
+        title: ახალი პერსონალიზირებული ემოჯის დამატება
+      overwrite: გადაწერა
+      shortcode: მოკლე-კოდი
+      shortcode_hint: მინ. 2 ნიშანი, მხოლოდ ალფანუმერიკული ნიშნები და "ქვედა-ტირეები"
+      title: პერსონალიზირებული ემოჯიები
+      unlisted: ჩამოუთვლელი
+      update_failed_msg: ემოჯის განახლება ვერ მოხერხდა
+      updated_msg: ემოჯი წარმატებით განახლდა!
+      upload: ატვირთვა
+    dashboard:
+      backlog: დაუსრულებელი საქმეები
+      config: კონფიგურაცია
+      feature_deletions: ანგარიშის გაუქმებები
+      feature_invites: მოწვევის ბმულები
+      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>გაჩუმება</strong> გახდის ანგარიშის პოსტებს უჩინარს ყველასთვის, ვინც მას არ მიჰყვება. <strong>შეჩერება</strong> გააუქმებს ანგარიშის მთელ კონტენტს, მედიას და პროფილის მონაცემს. გამოიყენეთ <strong>არც ერთი</strong> თუ გსურთ უბრალოდ უარყოთ ფაილები."
+          noop: არც ერთი
+          silence: გაჩუმება
+          suspend: შეჩერება
+        title: ახალი დომენის ბლოკი
+      reject_media: მედია ფაილების უარყოფა
+      reject_media_hint: შლის ლოკალურად შენახულ მედია ფაილებს და უარყოფს სამომავლო გადმოტვირთებს. შეუსაბამო შეჩერებებისთვის
+      show:
+        affected_accounts:
+          one: გავლენა იქონია მონაცემთა ბაზაში ერთ ანგარიშზე
+          other: გავლენა იქონიო მონაცემთა ბაზაში %{count} ანგარიშზე
+        retroactive:
+          silence: ამ დომენში ყველა არსებულ ანგარიშზე გაჩუმების მოშორება
+          suspend: ამ დომენში ყველა არსებულ ანგარიშზე შეჩერების მოშორება
+        title: უკუაქციეთ დომენის ბლოკი %{domain} დომენზე
+        undo: უკუქცევა
+      undo: უკუქცევა
+    email_domain_blocks:
+      add_new: ახლის დამატება
+      created_msg: ელ-ფოსტის დომენი წარმატებით დაემატა შავ სიას
+      delete: გაუქმება
+      destroyed_msg: ელ-ფოსტის დომენი წარმატებით ამოიშალა შავი სიიდან
+      domain: დომენი
+      new:
+        create: დომენის დამატება
+        title: ელ-ფოსტის ახალი შენატანი შავ სიაში
+      title: ელ-ფოსტის შავი სია
+    instances:
+      title: ცნობილი ინსტანციები
+    invites:
+      deactivate_all: ყველას დეაქტივაცია
+      filter:
+        all: ყველა
+        available: ხელმისაწვდომი
+        expired: ვადაგასული
+        title: ფილტრი
+      title: მოწვევები
+    relays:
+      add_new: ახელი რილეი
+      description_html: "<strong>ფედერაციის რილეი</strong> შუამავალი სერვერია, რომელიც ცვლის საჯარო ტუტების დიდ ოდენობას იმ სერვერებს შორის, რომლებიც გამოიწერენ და მასზე გამოაქვეყნებენ. <strong>ეს მცირე და საშუალო სერვერებს ეხმარება აღმოაჩინონ კონტენტი ფედივერსისგან</strong>, რომელიც სხვა შემთხვევაში მომხარებლებს აიძულებდა მექნიკურ რეჟიმში გაჰყოლოდნენ ხალხს სხვა დისტანციურ სერვერებზე."
+      enable_hint: ამოქმდების შემდეგ, თქვენი სერვერი გამოიწერს ყველა საჯარო ტუტს ამ რილეიდან და დაიწყებს სერვერის ღია ტუტების იქ გაგზავნას.
+      inbox_url: რილეი ურლ
+      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: ბიზნეს ელ-ფოსტა
+        username: საკონტაქტო მომხმარებლის სახელი
+      hero:
+        desc_html: წინა გვერდზე გამოჩენილი. მინ. 600/100პიქს. რეკომენდირებული. როდესაც არაა დაყენებული, ჩნდება ინსტანციის პიქტოგრამა
+        title: გმირი სურათი
+      peers_api_enabled:
+        desc_html: დომენების სახელები რომლებსაც შეხვდა ეს ინსტანცია ფედივერსში
+        title: გამოაქვეყნე აღმოჩენილი ინსტანციების სია
+      preview_sensitive_media:
+        desc_html: ბმულის პრევიუები სხვა ვებ-საიტებზე გამოაჩენენ პიქტოგრამას, მაშინაც კი თუ მედია მონიშნულია მგრძნობიარედ
+        title: გამოაჩინე მგრძნობიარე მედია ოუფენ-გრეფ პრევიუებში
+      registrations:
+        closed_message:
+          desc_html: გამოჩნდება წინა გვერდზე, როდესაც რეგისტრაციები დახურულია. შეგიძლიათ გამოიყენოთ ჰტმლ ტეგები
+          title: დახურული რეგისტრაციის წერილი
+        deletion:
+          desc_html: უფლება მიეცით ყველას, გააუქმონ თავიანთი ანგარიში
+          title: ღია ანგარიშის გაუქმება
+        min_invite_role:
+          disabled: არავინ
+          title: ნება დაერთოს მოწვეევებს
+        open:
+          desc_html: უფლება მიეცით ყველას, გახსნან ანგარიში
+          title: ღია რეგისტრაცია
+      show_known_fediverse_at_about_page:
+        desc_html: ჩართვისას, ეს გამოაჩენს ტუტებს ყველა ცნობილი ფედივერსისგან პრევიუზე. სხვა შემთხვევაში, გამოაჩენს მხოლოდ ლოკალურ ტუტებს.
+        title: გამოჩნდეს ცნობილი ვედივერსი თაიმლაინ პრევიუში
+      show_staff_badge:
+        desc_html: გამოჩნდეს სტაფის ნიშანი მომხმარებლის გვერდზე
+        title: სტაფის ნიშნის გამოჩენა
+      site_description:
+        desc_html: საშესავლო პარაგრაფი წინა გვერდზე. აღწერეთ თუ რა ხდის ამ მასტოდონის სერვერს განსაკუთრებულს და სხვა მნიშვნელოვანი. შეგიძლიათ გამოიყენოთ ჰტმლ ტეგები, კერძოდ <code>&lt;a&gt;</code> და <code>&lt;em&gt;</code>.
+        title: ინსტანციის აღწერილობა
+      site_description_extended:
+        desc_html: კარგი ადგილი მოქცევის კოდექსისთვის, წესები, სახელმძღვანელოები და სხვა რაც გამოარჩევს თქვენს ინსტანციას. შეგიძლიათ გამოიყენოთ ჰტმლ ტეგები
+        title: პერსონალიზირებული განვრცობილი ინფორმაცია
+      site_short_description:
+        desc_html: გამოჩნდება გვერდით ბარში და მეტა ტეგებში. აღწერეთ თუ რა არის მასტოდონი და რა ხდის ამ სერვერს უნიკალურს ერთ პარაგრაფში. თუ ცარიელია, გამოჩნდება ინსტანციის აღწერილობა.
+        title: აჩვენეთ ინსტანციის აღწერილობა
+      site_terms:
+        desc_html: შეგიძლიათ დაწეროთ საკუთარი კონფიდენციალურობის პოლიტიკა, მომსახურების პირობები ან სხვა იურიდიული დოკუმენტი. შეგიძლიათ გამოიყენოთ ჰტმლ ტეგები
+        title: პერსონალიზირებული მომსახურების პირობები
+      site_title: ინსტანციის სახელი
+      thumbnail:
+        desc_html: გამოიყენება პრევიუებისთვის ოუფენ-გრეფში და აპი-ში. 1200/630პიქს. რეკომენდირებული
+        title: ინსტანციის პიქტოგრამა
+      timeline_preview:
+        desc_html: აჩვენეთ საჯარო თაიმლაინი ლენდინგ გვერდზე
+        title: თაიმლაინ პრევიუ
+      title: საიტის პარამეტრები
+    statuses:
+      back_to_account: უკან ანგარიშის გვერდისკენ
+      batch:
+        delete: გაუქმება
+        nsfw_off: მონიშნე არა-მგრძნობიარედ
+        nsfw_on: მონიშნე მგრძნობიარედ
+      failed_to_execute: ვერ გაეშვა
+      media:
+        title: მედია
+      no_media: არაა მედია
+      no_status_selected: სატუსები არ შეცვლილა, რადგან არცერთი არ მონიშნულა
+      title: ანგარიშის სტატუსები
+      with_media: მედიით
+    subscriptions:
+      callback_url: ქოლბექ ურლ
+      confirmed: დამოწმდა
+      expires_in: ვადა გასდის
+      last_delivery: ბოლო მიღება
+      title: ვებ-საბი
+      topic: სათაური
+    title: ადმინისტრაცია
+  admin_mailer:
+    new_report:
+      body: "%{reporter}-მა დაარეპორტა %{target}"
+      body_remote: ვიღაცამ %{domain}-იდან დაარეპორტა %{target}
+      subject: ახალი რეპორტი %{instance} (#%{id})-ზე
+  application_mailer:
+    notification_preferences: შეცვალეთ ელ-ფოსტის პრეფერნსიები
+    salutation: "%{name},"
+    settings: 'შეცვალეთ ელ-ფოსტის პრეფერენსიები: %{link}'
+    view: 'ჩვენება:'
+    view_profile: პროფილის ჩვენება
+    view_status: სტატუსის ჩვენება
+  applications:
+    created: აპლიკაცია წარმატებით შეიქმნა
+    destroyed: აპლიკაცია წარმატებით გაუქმდა
+    invalid_url: მოწოდებული ურლ არასწორია
+    regenerate_token: წვდომის ტოკენის რეგენერაცია
+    token_regenerated: წვდომის ტოკენის რეგენერაცია მოხერხდა
+    warning: იყავით ძალიან ფრთხილად ამ მონაცემთან. არასდროს გააზიაროთ ეს!
+    your_token: თქვენი წვდომის ტოკენი
+  auth:
+    agreement_html: რეგისტრაციით თქვენ ეთანხმებით <a href="%{rules_path}">ინსტანციის წესებს</a> და <a href="%{terms_path}">ჩვენ მომსახურების პირობებს</a>.
+    change_password: პაროლი
+    confirm_email: ელ-ფოსტის დამოწმება
+    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: ან
+    or_log_in_with: ან გამოიყენეთ
+    providers:
+      cas: ქეს
+      saml: სამლ
+    register: რეგისტრაცია
+    register_elsewhere: რეგისტრაცია სხვა სერვერზე
+    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: ეს <strong>სამუდამოდ, დაუბრუნებლად</strong> გააუქმებს კონტენტს თქვენი ანგარიშიდან და მოახდენს მის დეაქტივაციას. მომხმარებლის სახელი კი, სამომავლო იმპერსონაციების შესაჩერებლად, გახდება რეზერვირებული.
+    proceed: ანგარიშის გაუქმება
+    success_msg: თქვენი ანგარიში წარმატებით გაუქმდა
+    warning_html: მოცულობის გაუქმება გარანტირებულია მხოლოდ ამ ინსტანციაზე. კონტენტი რომელიც ფართო მასშტაბით გაზიარდა უფრო დატოვებს კვალს. ოფლაინ სერვერები და სერვერები, რომლებმაც შეწყვიტეს თქვენი განახლებების გამოწერა არ განაახლებენ მონაცემთა ბაზებს.
+    warning_title: წვდომა გავრცელებულ კონტენტზე
+  errors:
+    '403': ამ გვერდის ხილვის უფლება არ გაქვთ.
+    '404': გვერდი რომელსაც ეძებთ არ არსებობს.
+    '410': გვერდი რომელსაც ეძებდით აღარ არსებობს.
+    '422':
+      content: უსაფრთხოების ვერიფიკაცია ვერ მოხერხდა. ბლოკავთ ქუქის?
+      title: უსაფრთხოების ვერიფიკაცია არ შედგა
+    '429': დარტყმა
+    '500':
+      content: ბოდიში, ჩვენ მხარეს რაღაც არია.
+      title: გვერდი არაა სწორი
+    noscript_html: მასტოდონ ვებ-აპლიკაციის გამოყენებისთვის, გთხოვთ ჩართოთ ჯავასკრიპტი. სხვა შემთხვევაში, მასტოდონის თქვენი პატფორმისთვის სცადეთ გამოიყენოთ ერთ-ერთი <a href="%{apps_path}">მშობლიური აპლიკაცია</a>.
+  exports:
+    archive_takeout:
+      date: თარიღი
+      download: ჩამოტვირთეთ თქვენი არქივი
+      hint_html: შეგიძლიათ მოითხოვოთ თქვენი აქივი <strong>ტუტებისა და ატვირთული მედიისა</strong>. ექსპორტირებული მონაცემები იქნება ექთივითი-ფაბ ფორმატში, წაკითხვადი ნებისმიერი თავსებადი პროგრამით. არქივის მოთხოვნა შეგიძლიათ 7 დღეში ერთხელ.
+      in_progress: მიმდინარეობს თქვენი არქივის შედგენა...
+      request: თქვენი არქივის მოთხოვნა
+      size: ზომა
+    blocks: თქვენ ბლოკავთ
+    csv: ცსვ
+    follows: თქვენ მიჰყვებით
+    mutes: თქვენ აჩუმებთ
+    storage: მედია საცავი
+  filters:
+    contexts:
+      home: სახლის თაიმლაინი
+      notifications: შეტყობინებები
+      public: საჯარო თაიმლაინი
+      thread: საუბრები
+    edit:
+      title: ფილტრის ცვლილება
+    errors:
+      invalid_context: მოწოდებულია არასწორი ან ცარიელი კონტექსტი
+      invalid_irreversible: დაუბრუნებელი ფილტრაცია მუშაობს მხოლოდ სახლის ან ნოტიფიკაციის კონტექსტში
+    index:
+      delete: გაუქმება
+      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:
+    changes_saved_msg: ცვლილებები წარმატებით დამახსოვრდა!
+    save_changes: ცვლილებების შენახვა
+    validation_errors:
+      one: რაღაც ჯერ არაა მთლად კარგად! გთხოვთ განიხილოთ ქვემოთ მოცემული შეცდომები
+      other: რაღაც ჯერ არაა მთლად კარგად! გთხოვთ განიხილოთ ქვემოთ მოცემული %{count} შეცდომა
+  imports:
+    preface: შეგიძლიათ დააიმპორტოთ მონაცემები, რომლებიც დააექსპორტეთ სხვა სერვერიდან, მაგალითად ადამიანების სია, რომლებსაც მიჰყვებით ან ბლოკავთ.
+    success: თქვენი მონაცემები წარმატებით აიტვირთა და მათი პროცესირება მოხდება გარკვეულ დროში
+    types:
+      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:
+        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: საჭირო გადამისამართების ურლ თქვენი ანგარიშისთვის ვერ მოიძებნა
+    no_account_html: არ გაქვთ ანგარიში? შეგიძლიათ <a href='%{sign_up_path}' target='_blank'>დარეგისტრირდეთ აქ</a>
+    proceed: გააგრძელეთ გასაყოლად
+    prompt: 'თქვენ გაჰყვებით:'
+  remote_unfollow:
+    error: შეცდომა
+    title: სათაური
+    unfollowed: დადევნების შეწყვეტა
+  sessions:
+    activity: ბოლო აქტივობა
+    browser: ბრაუზერი
+    browsers:
+      alipay: ალიფეი
+      blackberry: ბლექბერი
+      chrome: ქრომი
+      edge: მაიკროსოფთ ედჯი
+      electron: ელექტრონი
+      firefox: ფაირფოქსი
+      generic: ამოუცნობი ბრაუზერი
+      ie: ინტერნეტ ექფლორერი
+      micro_messenger: მიკრო-მესინჯერი
+      nokia: ნოკია ს40 ოვი ბრაუზერი
+      opera: ოპერა
+      otter: ოტერი
+      phantom_js: ფანტომჯეიესი
+      qq: ქქ ბრაუზერი
+      safari: საფარი
+      uc_browser: იუსიბიბრაუზერი
+      weibo: ვეიბო
+    current_session: მიმდინარე სესია
+    description: "%{browser} %{platform}-ზე"
+    explanation: ეს ვებ-ბრაუზერებია, რომლებიც ამჟამად აუტენტიფიცირებულ არიან თქვენს მასტოდონ ანგარიშთან.
+    ip: აი-პი
+    platforms:
+      adobe_air: ედობ ეარი
+      android: ანდროიდი
+      blackberry: ბლექბერი
+      chrome_os: ქრომო-ოსი
+      firefox_os: ფაირფოქს-ოსი
+      ios: აი-ოსი
+      linux: ლინუქსი
+      mac: მაკი
+      other: ამოუცნობი პლატფორმა
+      windows: ვინდოუსი
+      windows_mobile: ვინდოუს მობაილი
+      windows_phone: ვინდოუს ფოუნი
+    revoke: გაუქმება
+    revoke_success: სესია წარმატებით გაუქმდა
+    title: სესიები
+  settings:
+    authorized_apps: ავტორიზირებული აპლიკაციები
+    back: უკან მასტოდონისკენ
+    delete: ანგარიშის გაუქმება
+    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: ვებში გახნსა
+    over_character_limit: ნიშნების ლიმიტი გადასცდა %{max}-ს
+    pin_errors:
+      limit: ტუტების მაქსიმალური რაოდენობა უკვე აპინეთ
+      ownership: სხვისი ტუტი ვერ აიპინება
+      private: არა-საჯარო ტუტი ვერ აიპინება
+      reblog: ბუსტი ვერ აიპინება
+    show_more: მეტის ჩვენება
+    sign_in_to_participate: საუბარში მონაწილეობისთვის გაიარეთ ავტორიზაცია
+    title: '%{name}: "%{quote}"'
+    visibilities:
+      private: მხოლოდ-მიმდევრები
+      private_long: აჩვენე მხოლოდ მიმდევრებს
+      public: საჯარო
+      public_long: ხედავს ყველა
+      unlisted: ჩამოუთვლელი
+      unlisted_long: ხედავს ყველა, მაგრამ არ ჩანს საჯარო თაიმლაინებში
+  stream_entries:
+    pinned: აპინული ტუტი
+    reblogged: გაზრდილი
+    sensitive_content: მგრძნობიარე კონტენტი
+  terms:
+    body_html: |
+      <h2>კონფიდენციალურობის პოლიტიკა</h2>
+      <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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">რაში ვიყენებთ ინფორმაციას?</h3>
+
+      <p>ნებისმიერი სხვა ინფორმაცია, რომელსაც ვაგროვებთ თქვენგან შესაძლოა გამოყენებულ იქნას შემდეგი გზებით:</p>
+
+      <ul>
+        <li>რომ უზრუნველვყოთ მასტოდონის მთავარი ფუნქციონალი. შეგიძლიათ ინტერაქცია გაუწიოთ მხოლოდ სხვის კონტენტს და შექმნათ პოსტები მაშინ როდესაც ავტორიზებული ხართ. მაგალითად, შესაძლოა გაჰყვეთ სხვა ადამიანებს, რათა იხილოთ მათი ჯამური პოსტები საკუთარ პერსონალიზებულ სახლის თაიმლაინზე.</li>
+        <li>რომ შევუწყვოთ ხელი საზოგადოების მოდერაციას, მაგალითად შევადაროთ თქვენი აი-პი მისამართი სხვა ცნობილ მისამართებს, რათა ამოვიცნოთ ბანის გადაუხდელობა ან სხვა დარღვევები.</li>
+        <li>ელ-ფოსტის მისამართი რომელსაც გვაწვდით, შესაძლოა გამოვიყენოთ თქვენთვის ინფორმაციის გამოსაგძავნად, შეგატყობინოთ სხვა ადამიანების ინტერაქციაზე თქვენს კონტენტთან ან თქვენთვის გამოგზავნილ წერილებზე, ასევე რომ გიპასუხოთ მოთხოვნებზე და/ან სხვა საკითხებზე.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">როგორ ვიცავთ თქვენს ინფორმაციას?</h3>
+
+      <p>მიღებული გვაქვს სხვადასხვა ზომა, შევინარჩუნოთ თქვენი პირადი ინფორმაციის უსაფრთხოება, რომელსაც აგზავნით, შეგყავთ ან კითხულობთ. ამ ყველაფერთან ერთად თქვენი ბრაუზერის სესია, ტრეფიკი თქვენს აპლიკაციასა და აპის შორის დაცულია სსლ-ით, თქვენი პაროლი იშიფრება ძლიერი ალგორითმით. შეგიძლიათ ჩართოთ მეორე-ფაქტორის აუტენტიფიკაცია, რათა გააღმაოთ თქვენი ანგარიშის თავდაცვა.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">რა არის ჩვენი მონაცემის უარყოფის პოლიტიკა?</h3>
+
+      <p>ჩვენ არ დავიშურებთ ძალისხმევას რომ:</p>
+
+      <ul>
+        <li>შევინარჩუნოთ სერვერის ლოგები, რომლებიც მოიცავენ ყველა მოთხოვნის აი-პი მისამართს, თუმცა ესეთი ლოგები არ ინახება 90 დღეზე მეტ ხანს.</li>
+        <li>შევინარჩუნოთ რეგისტრირებული მომხმარებლების აი-პი მისამართები მაქსიმუმ 12 თვით.</li>
+      </ul>
+
+      <p>შეგიძლიათ მოითხოვოთ და ჩამოტვირთოთ თქვენი კონტენტის არქივი, რომელიც მოიცავს თქვენს პოსტებს, მედია ფაილებს, პროფილის და დასათაურების სურათს.</p>
+
+      <p>შეგიძლიათ დაუბრუნებლად გააუქმოთ თქვენი ანგარიში ნებისმიერ დროს.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">ვიყენებთ თუ არა ქუქის?</h3>
+
+      <p>დიახ. ქუქიები წარმოადგენენ პატარა ფაილებს, რომელთაც, საიტი ან სერვის-პროვაიდერი, ათავსებს თქვენი კომპიუტერის მყარ დისკზე, ვებ-ბრაუზერის (თუ ნებას რთავთ) მეშვეობით. ქუქიები საშუალებას აძლევს საიტს ამოიცნონ თქვენი ბრაუზზერი და თუ გაქვთ რეგისტრირებული ანგარიში მისი ასოციაცია მოახდინონ თქვენს ანგარიშთან.</p>
+
+      <p>ჩვენ ვიყენებთ ქუქის, ვიცოდეთ და შევინახოთ თქვენი პრეფერენსიები სამომავლო სტუმრობებისთვის.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">ვამჟღავნებთ თუ არა ინფორმაციას გარე მხარეებისთვის?</h3>
+
+      <p>ჩვენ არ ვყიდით, ვვაჭრობთ ან გადაქვაქ თქვენთვის პირადად იდენტიფიცირებადი ინფორმაცია სხვა მხარეებისთვის. ეს არ მოიცავს სანდო მხარეებს, რომლებიც გვეხმარება საიტის ოპერირებაში, ჩვენი საქმიანობის ჩატარებაში, ან თქვენთვის მომსახურების გაწევაში, წინაპირობით კონფიდენციალურად შეინახონ თქვენი ინფორმაცია. ჩვენ შესაძლოა გამოვაქვეყნოთ თქვენი ინფორმაცია, რომელიც შესაბამისად შეიძლება ჩავთვალოთ კანონმდებლობასთან შეთავსებისთვის, აღვასრულოთ პოლიტიკა ან დავიცვათ ჩვენი ან სხვისი უფლებები, კუთვნილება ან უსაფრთხოება.</p>
+
+      <p>თქვენი საჯარო ინფორმაცია შესაძლოა ჩამოტვირთულ იქნას სხვა სერვერების მიერ ქსელში. თქვენი ღია და მიმდევრებზე გათვლილი პოსტები მიეწოდება სერვერებს სადაც თქვენი მიმდევრები მოღვაწეობენ, იმ შემთხვევაში თუ მიმღებები მომდინარეობენ სხვა სერვერიდან, პირდაპირი წერილები მიეწოდებათ მიმღებების სერვერებს.</p>
+
+      <p>როდესაც უფლებას მისცემთ აპლიკაციას გამოიყენოს თქვენი ანგარიში, უფლებებისგან გამომდინარე, მან შესაძლოა მოიპოვოს თქვენი საჯარო ინფორმაცია, თქვენი დადევნების სიები, თქვენი მიმდევრები, თქვენი სიები, ყველა პოსტი და თქვენი ფავორიტები. აპლიკაციები ვერასდროს იქონიებენ წვდომას თქვენი ელ-ფოსტის მისამართზე ან პაროლზე.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">საიტის მოხმარებს ბავშვების მიერ</h3>
+
+      <p>თუ ეს სერვერი მდებარეობს ეუ-ში ან ეეა-ში: ჩვენი საიტი, პროდუქტები და სერვისები მიმართულია ადამიანებისთვის, რომელთაც შეუსრულდათ 16 წელი. თუ თქვენი ასაკი 16 წელიწადზე ნაკლებია, ჯიდიფიარის (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">ზოგადი მონაცემების დაცვის რეგულაცია/a>) მოთხოვნის მიხედვით არ გამოიყენოთ ეს საიტი.</p>
+
+      <p>თუ ეს სერვერი მდებარეობს ა.შ.შ.-ში: ჩვენი საიტი პროდუქტი და სერვისები მიმართულია ადამიანებისთვის, რომელთაც შეუსრულდათ 13 წელი. თუ თქვენი ასაკი 13 წელიწადზე ნაკლებია, კოპპას (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">ბავშვთა ონლაინ კონფიდენციალურობის დაცვის აქტი</a>) მოთხოვნების მიხედვით არ გამოიყენოთ ეს საიტი.</p>
+
+      <p>იურიდიული მოთხოვნილებები შეიძლება განსხვავდებოდეს, თუ ეს სერვერი იმყოფება სხვა იურისდიქციის ქვეშ.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">ცვლილებები კონფიდენციალურობის პოლიტიკაში</h3>
+
+      <p>თუ გადავწყვეტთ შევცვალოთ კონფიდენციალურობის პოლიტიკა, გამოვაქვეყნებთ ამ გვერდზე.</p>
+
+      <p>ეს დოკუმენტი არის ცც-ბაი-სა. ეს ბოლოს განახლდა 2018 წლის, 17 აგვისტოს.</p>
+
+      <p>საწყისად ადაპტირებულია <a href="https://github.com/discourse/discourse">გამჟღავნების კონფიდენციალური პოლიტიკისგან</a>.</p>
+    title: "%{instance} მომსახურების პირობები და კონფიდენციალურობის პოლიტიკა"
+  themes:
+    contrast: მაღალი კონტრასტი
+    default: მასტოდონი
+    mastodon-light: მასტოდონი (ღია)
+  time:
+    formats:
+      default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
+  two_factor_authentication:
+    code_hint: დასამოწმებლად შეიყვანეთ თქვენი აუტენტიფიკატორ აპლიკაციისგან გენერირებული კოდი
+    description_html: თუ ჩართავთ <strong>მეორე-ფაქტორის აუტენტიფიკაციას</strong>, შესვლისას აუცილებელი იქნება ფლობდეთ ტელეფონს, რომელიც დააგენერირებს შესვლის ტოკენებს.
+    disable: გათიშვა
+    enable: ჩართვა
+    enabled: მეორე-ფაქტორის აუტენტიფიკაცია ჩართულია
+    enabled_success: მეორე-ფაქტორის აუტენტიფიკაცია წარმატებით ჩაირთო
+    generate_recovery_codes: აღდგენის კოდების გენერაცია
+    instructions_html: "<strong>დაასკანირეთ ეს ქრ კოდი გუგლ აუტენტიფიკატორში ან მსგავს ტოტპ აპლიკაციაში თქვენს ტელეფონზე</strong>. ამიერიდან, ეს აპლიკაცია დააგენერირებს ტოკენებს მაშინ როდესაც დაგჭირდებათ ავტორიზაცია."
+    lost_recovery_codes: აღდგენის კოდები უფლებას გაძლევთ მიიღოთ ხელმეორე წვდომა თქვენი ანგარიშისადმი თუ დაკარგავთ ტელეფონს. თუ დაკარგეთ აღდგენის კოდები, მათ რეგენერაცია შეგიძლიათ აქ. ძველი აღდგენის კოდები აღარ იქნება ვალიდური.
+    manual_instructions: 'თუ ვერ ასკანირებთ ქრ კოდს და საჭიროებთ მის მექანიკურ რეჟიმში შეყვანას, აქ არის ჩვეულებრივი ტექსტური საიდუმლო:'
+    recovery_codes: გაუწიეთ აღდგენის კოდებს რეზერვაცია
+    recovery_codes_regenerated: აღგენის კოდების რეგენერაცია წარმატებით შესრულდა
+    recovery_instructions_html: თუ როდესმე დაკარგავთ წვდომას თქვენს ტელეფონთან, შეგიძლიათ ქვემოთ მოცემული აღდგენის კოდები გამოიყენოთ, რათა მოიპოვოთ ხელმეორე წვდომა თქვენი ანგარიშისადმი. <strong>იქონიეთ აღდგენის კოდები დაცულად</strong>. მაგალითისთვის, შეგიძლიათ ამობეჭდოთ და შეინახოთ სხვა საბუთებთან ერთად.
+    setup: დაყენება
+    wrong_code: შეყვანილი კოდი არ იყო სწორი! სწორია სერვერის და მოწყობილობის დრო?
+  user_mailer:
+    backup_ready:
+      explanation: თქვენ მოითხოვეთ თქვენი მასტოდონის ანგარიშის სრული რეზერვაცია. ის ახლა უკვე მზადაა გადმოსაწერად!
+      subject: თქვენი არქივი გადმოსაწერად მზადაა
+      title: არქივის მიღება
+    welcome:
+      edit_profile_action: პროფილის მოწყობა
+      edit_profile_step: შეგიძლიათ მოაწყოთ თქვენი პროფილი ავატარის ატვირთვით, დასათაურების სურათით, თქვენი დისპლეი სახელის შეცვლით და სხვა. თუ გსურთ გაუწიოთ ახალ მიმდევრებს რევიუ, სანამ რეალურად გამოგყვებიან, შეგიძლიათ ჩაკეტოთ თქვენი ანგარიში.
+      explanation: აქ რამდენიმე რჩევაა დასაწყისისთვის
+      final_action: დაიწყე პოსტვა
+      final_step: 'დაიწყე პოსტვა! თქვენი ღია წერილები შესაძლოა ნახონ სხვებმა მიმდევრების გარეშეც კი, მაგალითად თქვენს ლოკალურ თაიმლაინზე ან ჰეშტეგებში. შეგიძლიათ წარადგინოთ თქვენი თავი #introductions ჰეშტეგით.'
+      full_handle: თქვენი სრული სახელური
+      full_handle_hint: ეს არის ის რასაც ეტყვით თქვენს მეგობრებს, რათა მოგწერონ ან გამოგყვნენ სხვა ინსტანციიდან.
+      review_preferences_action: შეცვალეთ პრეფერენსიები
+      review_preferences_step: დარწმუნდით რომ აყენებთ თქვენს პრეფერენსიებს, მაგალითად რა ელ-ფოსტის წერილების მიღება გსურთ, ან კონფიდენციალურობის რა დონე გსურთ ჰქონდეთ თქვენს პოსტებს საწყისად. თუ არ გაღიზიანებთ მოძრაობა, შეგიძლიათ ჩართოთ გიფის ავტო-დაკვრა.
+      subject: კეთილი იყოს თქვენი მობრძანება მასტოდონში
+      tip_federated_timeline: ფედერალური თაიმლაინი მასტოდონის ქსელის ცეცხლოვანი ხედია. ის მოიცავს მხოლოდ იმ ადამიანებს, რომელთაგანაც გამოიწერეს თქვენმა მეზობლებმა, ასე რომ ეს არაა სრული.
+      tip_following: თქვენ საწყისად მიჰყვებით თქვენი სერვერის ადმინისტრატორ(ებ)ს. უფრო საინტერესო ადამიანების მოსაძებნად იხილეთ ლოკალური და ფედერალური თაიმლაინები.
+      tip_local_timeline: ლოკალური თაიმლაინი ცეცხლოვანი ხედია ადამიანებისთვის %{instance}-ზე. ისინი არიან თქვენი უსიტყვო მეზობლები!
+      tip_mobile_webapp: თუ თქვენი მობილური ბრაუზერი გთავაზობთ მასტოდონის სახლის-ეკრანზე დამატებას, შეძლებთ ფუშ შეტყობინებების მიღებას. ეს მრავალმხრივ მოქმედებს როგორც მშობლიური აპლიკაცია!
+      tips: რჩევები
+      title: კეთილი იყოს თქვენი მობრძანება, %{name}!
+  users:
+    invalid_email: ელ-ფოსტის მისამართი არაა მართებული
+    invalid_otp_token: არასწორი მეორე ფაქტორის კოდი
+    otp_lost_help_html: თუ დაკარგეთ წვდომა ორივეზე, შესაძლოა დაუკავშირდეთ %{email}-ს
+    seamless_external_login: შესული ხართ გარე სერვისით, აქედან გამომდინარე პაროლი და ელ-ფოსტის მისამართი არაა ხელმისაწვდომი.
+    signed_in_as: 'შესული ხართ როგორც:'
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index 9b742d18bab4261c2e58e36cdb025d69d13319af..bf6a8b7705d4597121a7bddd283d1c5499dd60dc 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -5,13 +5,13 @@ ko:
     about_mastodon_html: 마스토돈은 <em>오픈 소스 기반의</em> 소셜 네트워크 서비스 입니다. 상용 플랫폼의 대체로서 <em>분산형 구조</em>를 채택해, 여러분의 대화가 한 회사에 독점되는 것을 방지합니다. 신뢰할 수 있는 인스턴스를 선택하세요 &mdash; 어떤 인스턴스를 고르더라도, 누구와도 대화할 수 있습니다. 누구나 자신만의 마스토돈 인스턴스를 만들 수 있으며, 아주 매끄럽게 <em>소셜 네트워크</em>에 참가할 수 있습니다.
     about_this: 이 인스턴스에 대해서
     administered_by: '관리자:'
+    api: API
+    apps: 모바일 앱
     closed_registrations: 현재 이 인스턴스에서는 신규 등록을 받고 있지 않습니다.
     contact: 연락처
     contact_missing: 미설정
     contact_unavailable: N/A
-    description_headline: "%{domain} (은)는 무엇인가요?"
-    domain_count_after: 개의 인스턴스
-    domain_count_before: 연결된
+    documentation: 문서
     extended_description_html: |
       <h3>룰을 작성하는 장소</h3>
       <p>아직 설명이 작성되지 않았습니다.</p>
@@ -28,25 +28,41 @@ ko:
     hosted_on: "%{domain}에서 호스팅 되는 마스토돈"
     learn_more: 자세히
     other_instances: 다른 인스턴스
+    privacy_policy: 개인정보 정책
     source_code: 소스 코드
-    status_count_after: 툿
+    status_count_after:
+      one: 툿
+      other: 툿
     status_count_before: 툿 수
-    user_count_after: 명
+    terms: 이용약관
+    user_count_after:
+      one: 명
+      other: 명
     user_count_before: 사용자 수
     what_is_mastodon: 마스토돈이란?
   accounts:
+    choices_html: "%{name}의 추천:"
     follow: 팔로우
-    followers: 팔로워
+    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} 님을 팔로우 중인 계정"
-    posts: 툿
+    pin_errors:
+      following: 추천하려는 사람을 팔로우 하고 있어야 합니다
+    posts:
+      one: 툿
+      other: 툿
+    posts_tab_heading: 툿
     posts_with_replies: 툿과 답장
-    remote_follow: 리모트 팔로우
     reserved_username: 이 아이디는 예약되어 있습니다
     roles:
       admin: 관리자
@@ -54,6 +70,9 @@ ko:
       moderator: 모더레이터
     unfollow: 팔로우 해제
   admin:
+    account_actions:
+      action: 조치 취하기
+      title: "%{acct} 계정에 조정 취하기"
     account_moderation_notes:
       create: 모더레이션 노트 작성하기
       created_msg: 모더레이션 기록이 성공적으로 작성되었습니다!
@@ -73,6 +92,7 @@ ko:
       confirm: 확인
       confirmed: 확인됨
       confirming: 확인 중
+      deleted: 삭제됨
       demote: 모더레이터 강등
       disable: 비활성화
       disable_two_factor_authentication: 2단계 인증을 비활성화
@@ -80,16 +100,19 @@ ko:
       display_name: 이름
       domain: 도메인
       edit: 편집
-      email: E-mail
+      email: 이메일
       email_status: 이메일 상태
       enable: 활성화
-      enabled: 활성화된
+      enabled: 활성
       feed_url: 피드 URL
       followers: 팔로워 수
       followers_url: 팔로워 URL
       follows: 팔로잉 수
+      header: 헤더
       inbox_url: 수신함 URL
+      invited_by: 초대자
       ip: IP
+      joined: 가입
       location:
         all: ì „ì²´
         local: 로컬
@@ -99,6 +122,7 @@ ko:
       media_attachments: 첨부된 미디어
       memorialize: 메모리엄으로 전환
       moderation:
+        active: 활동
         all: ì „ì²´
         silenced: 침묵 중
         suspended: 정지 중
@@ -106,20 +130,18 @@ ko:
       moderation_notes: 모더레이션 기록
       most_recent_activity: 최근 활동
       most_recent_ip: 최근 IP
+      no_limits_imposed: 제한 없음
       not_subscribed: 구독하지 않음
-      order:
-        alphabetic: 알파벳 순
-        most_recent: 최근 순
-        title: 순서
       outbox_url: 발신함 URL
-      perform_full_suspension: 완전히 정지시키기
+      perform_full_suspension: 정지시키기
       profile_url: 프로필 URL
       promote: 모더레이터로 승급
       protocol: 프로토콜
       public: 전체 공개
       push_subscription_expires: PuSH 구독 기간 만료
-      redownload: 아바타 업데이트
+      redownload: 프로필 업데이트
       remove_avatar: 아바타 지우기
+      remove_header: 헤더 삭제
       resend_confirmation:
         already_confirmed: 이 사용자는 이미 확인되었습니다
         send: 다시 확인 이메일
@@ -138,27 +160,31 @@ ko:
       shared_inbox_url: 공유된 inbox URL
       show:
         created_reports: 이 계정에서 제출된 신고
-        report: ì‹ ê³ 
         targeted_reports: 이 계정에 대한 신고
       silence: 침묵
+      silenced: 침묵 됨
       statuses: 툿 수
       subscribe: 구독하기
+      suspended: 정지 됨
       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}의 툿을 삭제했습니다"
@@ -180,6 +206,7 @@ ko:
         unsuspend_account: "%{name}이 %{target}에 대한 정지를 해제했습니다"
         update_custom_emoji: "%{name}이 에모지 %{target}를 업데이트 했습니다"
         update_status: "%{name}이 %{target}의 상태를 업데이트 했습니다"
+      deleted_status: "(삭제됨)"
       title: 감사 기록
     custom_emojis:
       by_domain: 도메인
@@ -206,8 +233,30 @@ ko:
       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: 추가하기
+      add_new: 도메인 차단 추가하기
       created_msg: 도메인 차단 처리를 완료했습니다
       destroyed_msg: 도메인 차단이 해제되었습니다
       domain: 도메인
@@ -224,11 +273,13 @@ ko:
         title: 새로운 도메인 차단
       reject_media: 미디어 파일 거부하기
       reject_media_hint: 로컬에 저장된 미디어 파일을 삭제하고, 이후로도 다운로드를 거부합니다. 정지와는 관계 없습니다
-      severities:
-        noop: 없음
+      reject_reports: ì‹ ê³  ê±°ë¶€
+      reject_reports_hint: 이 도메인으로부터의 모든 신고를 무시합니다. 정지와는 무관합니다
+      rejecting_media: 미디어 거부
+      rejecting_reports: ì‹ ê³  ê±°ë¶€
+      severity:
         silence: 침묵
         suspend: ì •ì§€
-      severity: 심각도
       show:
         affected_accounts:
           one: 데이터베이스 중 1개의 계정에 영향을 끼칩니다
@@ -238,8 +289,7 @@ ko:
           suspend: 이 도메인에 존재하는 모든 계정의 계정 정지를 해제
         title: "%{domain}의 도메인 차단을 해제"
         undo: 실행 취소
-      title: 도메인 차단
-      undo: 실행 취소
+      undo: 도메인 차단 취소
     email_domain_blocks:
       add_new: 새로 추가
       created_msg: 이메일 도메인 차단 규칙을 생성했습니다
@@ -250,19 +300,47 @@ ko:
         create: 차단 규칙 생성
         title: 새 이메일 도메인 차단
       title: Email 도메인 차단
+    followers:
+      back_to_account: 계정으로 돌아가기
+      title: "%{acct}의 팔로워"
     instances:
-      account_count: 알려진 계정의 수
-      domain_name: 도메인 이름
-      reset: 리셋
-      search: 검색
-      title: 알려진 인스턴스들
+      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: "<strong>연합 릴레이</strong>는 서버들 사이에서 많은 양의 공개 툿을 구독하고 중개하는 서버입니다. <strong>이것은 중소 규모의 서버에서 연합우주를 발견하는 데에 도움을 줄 수 있습니다</strong>, 이제 로컬 유저들이 다른 서버의 유저들을 수동으로 팔로우 하지 않아도 됩니다."
+      disable: 비활성화
+      disabled: 비활성화 됨
+      enable: 활성화
+      enable_hint: 활성화 되면, 이 릴레이의 모든 공개 툿을 구독하고 이 서버의 공개 툿을 전송하게 됩니다.
+      enabled: 활성화 됨
+      inbox_url: 릴레이 URL
+      pending: 릴레이의 승인 대기중
+      save_and_enable: 저장하고 활성화
+      setup: 릴레이 연결 설정
+      status: 상태
+      title: 릴레이
     report_notes:
       created_msg: 리포트 노트가 성공적으로 작성되었습니다!
       destroyed_msg: 리포트 노트가 성공적으로 삭제되었습니다!
@@ -277,7 +355,6 @@ ko:
       comment:
         none: 없음
       created_at: 리포트 시각
-      id: ID
       mark_as_resolved: 해결 완료 처리
       mark_as_unresolved: 미해결로 표시
       notes:
@@ -288,20 +365,15 @@ ko:
         placeholder: 이 리포트에 대한 조치, 기타 관련 된 사항에 대해 설명합니다…
       reopen: 리포트 다시 열기
       report: 'ì‹ ê³  #%{id}'
-      report_contents: ë‚´ìš©
       reported_account: 신고 대상 계정
       reported_by: 신고자
       resolved: 해결됨
       resolved_msg: 리포트가 성공적으로 해결되었습니다!
-      silence_account: 계정을 침묵 처리
       status: 상태
-      suspend_account: 계정을 정지
-      target: 대상
       title: ì‹ ê³ 
       unassign: 할당 해제
       unresolved: 미해결
       updated_at: 업데이트 시각
-      view: 표시
     settings:
       activity_api_enabled:
         desc_html: 주별 로컬에 게시 된 글, 활성 사용자 및 새로운 가입자 수
@@ -311,16 +383,25 @@ ko:
         title: 새 유저가 팔로우 할 계정들
       contact_information:
         email: 공개할 메일 주소를 입력
-        username: 아이디를 입력
+        username: 연락 받을 관리자 유저네임
+      custom_css:
+        desc_html: 모든 페이지에 적용할 CSS
+        title: 커스텀 CSS
       hero:
         desc_html: 프론트페이지에 표시 됩니다. 최소 600x100픽셀을 권장합니다. 만약 설정되지 않았다면, 인스턴스의 썸네일이 사용 됩니다
         title: 히어로 이미지
+      mascot:
+        desc_html: 여러 페이지에서 보여집니다. 최소 293x205px을 추천합니다. 설정 되지 않은 경우, 기본 마스코트가 사용 됩니다
+        title: 마스코트 이미지
       peers_api_enabled:
         desc_html: 이 인스턴스가 페디버스에서 만났던 도메인 네임들
         title: 발견 된 인스턴스들의 리스트 발행
       preview_sensitive_media:
         desc_html: 민감한 미디어로 설정되었더라도 다른 웹사이트에서 링크 미리보기에 썸네일을 보여줍니다
         title: 민감한 미디어를 오픈그래프 미리보기에 보여주기
+      profile_directory:
+        desc_html: 유저들이 발견 될 수 있도록 허용
+        title: 프로필 디렉토리 활성화
       registrations:
         closed_message:
           desc_html: 신규 등록을 받지 않을 때 프론트 페이지에 표시됩니다. HTML 태그를 사용할 수 있습니다
@@ -341,11 +422,14 @@ ko:
         desc_html: 유저 페이지에 스태프 배지를 표시합니다
         title: 스태프 배지 표시
       site_description:
-        desc_html: 탑 페이지와 meta 태그에 사용됩니다. HTML 태그, 주로 <code>&lt;a&gt;</code>, <code>&lt;em&gt;</code> 같은 것을 사용 가능합니다.
+        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: 짧은 인스턴스 설명
       site_terms:
         desc_html: 당신은 독자적인 개인정보 취급 방침이나 이용약관, 그 외의 법적 근거를 작성할 수 있습니다. HTML태그를 사용할 수 있습니다
         title: 커스텀 서비스 이용 약관
@@ -367,6 +451,7 @@ ko:
       media:
         title: 미디어
       no_media: 미디어 없음
+      no_status_selected: 아무 것도 선택 되지 않아 아무 것도 바뀌지 않았습니다
       title: 계정 툿
       with_media: 미디어 있음
     subscriptions:
@@ -376,7 +461,21 @@ ko:
       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_report:
       body: "%{reporter} 가 %{target} 를 신고했습니다"
@@ -454,6 +553,16 @@ ko:
     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': 당신이 찾으려는 페이지는 존재하지 않습니다.
@@ -465,7 +574,7 @@ ko:
     '500':
       content: 죄송합니다, 뭔가 잘못 되었습니다.
       title: 이 페이지는 잘못되었습니다
-    noscript_html: 마스토돈을 사용하기 위해서는 자바스크립트를 켜 주십시오. 아니면 <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">네이티브 앱</a> 중 하나를 사용할 수 있습니다.
+    noscript_html: 마스토돈을 사용하기 위해서는 자바스크립트를 켜 주십시오. 아니면 <a href="%{apps_path}">네이티브 앱</a> 중 하나를 사용할 수 있습니다.
   exports:
     archive_takeout:
       date: 날짜
@@ -476,7 +585,9 @@ ko:
       size: 크기
     blocks: 차단
     csv: CSV
+    domain_blocks: 도메인 차단
     follows: 팔로우
+    lists: 리스트
     mutes: 뮤트
     storage: 미디어
   filters:
@@ -507,9 +618,13 @@ ko:
     true_privacy_html: "<strong>프라이버시 보호는 End-to-End 암호화로만 이루어 질 수 있다는 것에 유의</strong>해 주십시오."
     unlocked_warning_html: 누구든 여러분을 팔로우 할 수 있으며, 여러분의 프라이빗 투고를 볼 수 있습니다. 팔로우 할 수 있는 사람을 제한하고 싶은 경우 %{lock_link}에서 설정해 주십시오.
     unlocked_warning_title: 이 계정은 비공개로 설정되어 있지 않습니다
+  footer:
+    developers: 개발자
+    more: 더 보기…
+    resources: 리소스
   generic:
     changes_saved_msg: 정상적으로 변경되었습니다!
-    powered_by: "%{link}에 의해 제공"
+    copy: 복사
     save_changes: 변경 사항을 저장
     validation_errors:
       one: 오류가 발생했습니다. 아래 오류를 확인해 주십시오
@@ -545,8 +660,6 @@ ko:
       expires_at: 만료
       uses: 사용됨
     title: 초대
-  landing_strip_html: "<strong>%{name}</strong> 님은 %{link_to_root_path} 인스턴스의 사용자입니다. 계정을 가지고 있다면 팔로우 하거나 대화할 수 있습니다."
-  landing_strip_signup_html: 아직 계정이 없다면 <a href="%{sign_up_path}">여기서</a> 등록할 수 있습니다.
   lists:
     errors:
       limit: 리스트 최대치에 도달했습니다
@@ -618,15 +731,30 @@ ko:
     publishing: 퍼블리싱
     web: 웹
   remote_follow:
-    acct: 아이디@도메인을 입력해 주십시오
+    acct: 당신이 사용하는 아이디@도메인을 입력해 주십시오
     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: 마지막 활동
     browser: 브라우저
@@ -706,6 +834,7 @@ ko:
       private: 비공개 툿은 고정될 수 없습니다
       reblog: 부스트는 고정될 수 없습니다
     show_more: 더 보기
+    sign_in_to_participate: 로그인 하여 이 대화에 참여하기
     title: '%{name}: "%{quote}"'
     visibilities:
       private: 비공개
@@ -715,11 +844,91 @@ ko:
       unlisted: 공개 타임라인 비공개
       unlisted_long: 누구나 볼 수 있지만, 공개 타임라인에는 표시되지 않습니다
   stream_entries:
-    click_to_show: 클릭해서 표시
     pinned: 고정된 툿
     reblogged: 님이 부스트 했습니다
     sensitive_content: 민감한 컨텐츠
   terms:
+    body_html: |
+      <h2>개인정보 정책</h2>
+      <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>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">우리가 당신의 정보를 어디에 쓰나요?</h3>
+
+      <p>당신에게서 수집한 정보는 다음과 같은 곳에 사용 됩니다:</p>
+
+      <ul>
+        <li>마스토돈의 주요 기능 제공. 다른 사람의 게시물에 상호작용 하거나 자신의 게시물을 작성하기 위해서는 로그인을 해야 합니다. 예를 들어, 다른 사람의 게시물을 자신만의 홈 타임라인에서 모아 보기 위해 팔로우를 할 수 있습니다.</li>
+        <li>커뮤니티의 모더레이션을 위해, 예를 들어 당신의 IP 주소와 기타 사항을 비교하여 금지를 우회하거나 다른 규칙을 위반하는지 판단하는 데에 사용할 수 있습니다.</li>
+        <li>당신이 제공한 이메일 주소를 통해 정보, 다른 사람들의 반응이나 받은 메시지에 대한 알림, 기타 요청 등에 관한 응답 요청 등을 보내는 데에 활용됩니다.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">어떻게 당신의 정보를 보호하나요?</h3>
+
+      <p>우리는 당신이 입력, 전송, 접근하는 개인정보를 보호하기 위해 다양한 보안 대책을 적용합니다. 당신의 브라우저 세션, 당신의 응용프로그램과의 통신, API는 SSL로 보호 되며 패스워드는 강력한 단방향 해시 알고리즘을 사용합니다. 계정의 더 나은 보안을 위해 2단계 인증을 활성화 할 수 있습니다.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">자료 저장 정책은 무엇이죠?</h3>
+
+      <p>우리는 다음을 위해 노력을 할 것입니다:</p>
+
+      <ul>
+        <li>IP를 포함해 이 서버에 전송 되는 모든 요청에 대한 로그는 90일을 초과하여 저장되지 않습니다.</li>
+        <li>가입 된 유저의 IP 정보는 12개월을 초과하여 저장 되지 않습니다.</li>
+      </ul>
+
+      <p>당신은 언제든지 게시물, 미디어 첨부, 프로필 이미지, 헤더 이미지를 포함한 당신의 컨텐트에 대한 아카이브를 요청하고 다운로드 할 수 있습니다.</p>
+
+      <p>언제든지 계정을 완전히 삭제할 수 있습니다.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">쿠키를 사용하나요?</h3>
+
+      <p>네. 쿠키는 (당신이 허용한다면) 당신의 웹 브라우저를 통해 서버에서 당신의 하드드라이브에 저장하도록 전송하는 작은 파일들입니다. 이 쿠키들은 당신의 브라우저를 인식하고, 계정이 있는 경우 이와 연결하는 것을 가능하게 합니다.</p>
+
+      <p>당신의 환경설정을 저장하고 다음 방문에 활용하기 위해 쿠키를 사용합니다.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">외부에 정보를 공개하나요?</h3>
+
+      <p>우리는 당신을 식별 가능한 개인정보를 외부에 팔거나 제공하거나 전송하지 않습니다. 이는 당사의 사이트를 운영하기 위한, 기밀 유지에 동의하는, 신뢰 가능한 서드파티를 포함하지 않습니다. 또한 법률 준수, 사이트 정책 시행, 또는 당사나 타인에 대한 권리, 재산, 또는 안전보호를 위해 적절하다고 판단되는 경우 당신의 정보를 공개할 수 있습니다.</p>
+
+      <p>당신의 공개 게시물은 네트워크에 속한 다른 서버가 다운로드 할 수 있습니다. 당신의 팔로워나 수신자가 이 서버가 아닌 다른 곳에 존재하는 경우 당신의 공개, 팔로워 공개 게시물은 당신의 팔로워가 존재하는 서버로 전송되며, 다이렉트메시지는 수신자가 존재하는 서버로 전송 됩니다.</p>
+
+      <p>당신이 계정을 사용하기 위해 응용프로그램을 승인하는 경우 당신이 허용한 권한에 따라 응용프로그램은 당신의 공개 계정정보, 팔로잉 리스트, 팔로워 리스트, 게시물, 즐겨찾기 등에 접근이 가능해집니다. 응용프로그램은 절대로 당신의 이메일 주소나 패스워드에 접근할 수 없습니다.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">어린이의 사이트 사용</h3>
+
+      <p>이 서버가 EU나 EEA에 속해 있다면: 당사의 사이트, 제품과 서비스는 16세 이상인 사람들을 위해 제공됩니다. 당신이 16세 미만이라면 GDPR(<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>)의 요건에 따라 이 사이트를 사용할 수 없습니다.</p>
+
+      <p>이 서버가 미국에 속해 있다면: 당사의 사이트, 제품과 서비스는 13세 이상인 사람들을 위해 제공됩니다. 당신이 13세 미만이라면 COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>)의 요건에 따라 이 사이트를 사용할 수 없습니다.</p>
+
+      <p>이 서버가 있는 관할권에 따라 법적 요구가 달라질 수 있습니다.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">개인정보 정책의 변경</h3>
+
+      <p>만약 우리의 개인정보 정책이 바뀐다면, 이 페이지에 바뀐 정책이 포스트 됩니다.</p>
+
+      <p>이 문서는 CC-BY-SA 라이센스입니다. 마지막 업데이트는 2018년 3월 7일입니다.</p>
+
+      <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: "%{instance} 이용약관과 개인정보 취급 방침"
   themes:
     contrast: 고대비
@@ -728,6 +937,7 @@ ko:
   time:
     formats:
       default: "%Y년 %m월 %d일 %H:%M"
+      month: "%Yë…„ %b"
   two_factor_authentication:
     code_hint: 확인하기 위해서 인증 애플리케이션에서 표시된 코드를 입력해 주십시오
     description_html: "<strong>2단계 인증</strong>을 활성화 하면 로그인 시 전화로 인증 코드를 받을 필요가 있습니다."
@@ -749,6 +959,22 @@ ko:
       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: 아바타, 헤더를 업로드하고, 사람들에게 표시 될 이름을 바꾸는 것으로 당신의 프로필을 커스텀 할 수 있습니다. 사람들이 당신을 팔로우 하기 전에 리뷰를 거치게 하고 싶다면 계정을 잠그면 됩니다.
@@ -760,7 +986,6 @@ ko:
       review_preferences_action: 설정 바꾸기
       review_preferences_step: 당신의 설정을 확인하세요. 어떤 이메일로 알림을 받을 것인지, 기본적으로 어떤 프라이버시 설정을 사용할 것인지, 멀미가 없다면 GIF를 자동 재생하도록 설정할 수도 있습니다.
       subject: 마스토돈에 오신 것을 환영합니다
-      tip_bridge_html: 만약 트위터에서 오셨다면 <a href="%{bridge_url}">브리지 앱</a>을 통해 마스토돈에 있는 친구들을 찾을 수 있습니다. 친구들도 이 앱을 사용했을 때만 작동합니다!
       tip_federated_timeline: 연합 타임라인은 마스토돈 네트워크의 소방호스입니다. 다만 여기엔 당신의 이웃들이 구독 중인 것만 뜹니다, 모든 것이 다 오는 것은 아니예요.
       tip_following: 기본적으로 서버의 관리자를 팔로우 하도록 되어 있습니다. 흥미로운 사람들을 더 찾으려면 로컬과 연합 타임라인을 확인해 보세요.
       tip_local_timeline: 로컬 타임라인은 %{instance}의 소방호스입니다. 여기 있는 사람들은 당신의 이웃들이에요!
@@ -768,8 +993,12 @@ ko:
       tips: 팁
       title: 환영합니다 %{name} 님!
   users:
+    follow_limit_reached: 당신은 %{limit}명의 사람을 넘어서 팔로우 할 수 없습니다
     invalid_email: 메일 주소가 올바르지 않습니다
     invalid_otp_token: 2단계 인증 코드가 올바르지 않습니다
     otp_lost_help_html: 만약 양쪽 모두를 잃어버렸다면 %{email}을 통해 복구할 수 있습니다
     seamless_external_login: 외부 서비스를 이용해 로그인 했습니다, 패스워드와 이메일 설정을 할 수 없습니다.
     signed_in_as: '다음과 같이 로그인 중:'
+  verification:
+    explanation_html: '당신은 <strong>프로필 메타데이터의 링크 소유자임을 검증할 수 있습니다</strong>. 이것을 하기 위해서는, 링크 된 웹사이트에서 당신의 마스토돈 프로필을 역으로 링크해야 합니다. 역링크는 <strong>반드시</strong> <code>rel="me"</code> 속성을 가지고 있어야 합니다. 링크의 텍스트는 상관이 없습니다. 여기 예시가 있습니다:'
+    verification: 검증
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93
--- /dev/null
+++ b/config/locales/lv.yml
@@ -0,0 +1 @@
+{}
diff --git a/config/locales/ms.yml b/config/locales/ms.yml
index 2eff09e1b33eaeec99a2e9e762e5e0bcf73a0d99..e3c901eff84856a8af490c4a9d7974da12a5853e 100644
--- a/config/locales/ms.yml
+++ b/config/locales/ms.yml
@@ -1,6 +1,339 @@
 ---
 ms:
   about:
-    about_this: Mengenai
+    about_hashtag_html: Terdapat toot awam yang ditanda dengan <strong>#%{hashtag}</strong>. Anda boleh berinteraksi dengan mereka jika anda mempunyai akaun di mana-mana dunia persekutuan Mastodon.
+    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:'
-    contact: Hubungi
+    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
+    documentation: Pendokumenan
+    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?
+  accounts:
+    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!
+    people_followed_by: Orang yang %{name} ikuti
+    people_who_follow: Orang yang mengikut %{name}
+    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:
+    account_moderation_notes:
+      create: Tinggalkan nota
+      created_msg: Nota kawalan telah berjaya dicipta!
+      delete: Padam
+      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
+        label: Tukar Emel
+        new_email: Emel Baru
+        submit: Tukar Emel
+        title: Tukar Emel untuk %{username}
+      confirm: Sahkan
+      confirmed: Disahkan
+      confirming: Mengesahkan
+      demote: Turunkan pangkat
+      disable: Lumpuhkan
+      disable_two_factor_authentication: Lumpuhkan 2FA
+      disabled: Dilumpuhkan
+      display_name: Nama paparan
+      domain: Domain
+      edit: Tukar
+      email: Emel
+      email_status: Status Emel
+      enable: Bolehkan
+      enabled: Dibolehkan
+      feed_url: Suapan URL
+      followers: Pengikut
+      followers_url: URL Pengikut
+      follows: Mengikuti
+      inbox_url: URL mesej masuk
+      ip: Alamat IP
+      location:
+        all: Semua
+        local: Tempatan
+        remote: Jarak Jauh
+        title: Kedudukan
+      login_status: Status log masuk
+      media_attachments: Lampiran media
+      memorialize: Tukarkan menjadi akaun peringatan
+      moderation:
+        all: Semua
+        silenced: Disenyapkan
+        suspended: Digantungkan
+        title: Kawalan
+      moderation_notes: Nota kawalan
+      most_recent_activity: Aktiviti terbaru
+      most_recent_ip: IP terbaru
+      no_limits_imposed: Tiada had dikuatkuasakan
+      not_subscribed: Tiada langganan
+      outbox_url: URL mesej keluar
+      perform_full_suspension: Gantung
+      profile_url: URL profil
+      promote: Naikkan pangkat
+      protocol: Protokol
+      public: Awam
+      push_subscription_expires: Langganan PuSH tamat tempoh
+      redownload: Segarkan semula avatar
+      remove_avatar: Buang avatar
+      resend_confirmation:
+        already_confirmed: Pengguna ini telah disahkan
+        send: Hantar semula emel pengesahan
+        success: Emel pengesahan telah berjaya dihantar!
+      reset: Set semula
+      reset_password: Set semula kata laluan
+      resubscribe: Langgan semula
+      role: Kebenaran
+      roles:
+        admin: Pentadbir
+        moderator: Pengawal
+        staff: Kakitangan
+        user: Pengguna
+      salmon_url: URL Salmon
+      search: Cari
+      shared_inbox_url: URL Peti Masuk Berkongsi
+      show:
+        created_reports: Laporan yang dicipta oleh akaun ini
+        targeted_reports: Laporan yang dicipta berkaitan akaun ini
+      silence: Senyap
+      silenced: Disenyapkan
+      statuses: Status
+      subscribe: Langgan
+      suspended: Digantung
+      title: Akaun
+      unconfirmed_email: Emel Belum Disahkan
+      undo_silenced: Buang senyap
+      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"
+        change_email_user: "%{name} menukar alamat emel pengguna %{target}"
+        confirm_user: "%{name} mengesahkan alamat emel pengguna %{target}"
+        create_custom_emoji: "%{name} memuat naik emoji baru %{target}"
+        create_domain_block: "%{name} menyekat domain %{target}"
+        create_email_domain_block: "%{name} menyenaraihitamkan domain emel %{target}"
+        demote_user: "%{name} menurunkan pangkat pengguna %{target}"
+        destroy_custom_emoji: "%{name} membuang emoji %{target}"
+        destroy_domain_block: "%{name} membuang sekatan domain %{target}"
+        destroy_email_domain_block: "%{name} menyenaraiputihkan domain emel %{target}"
+        destroy_status: "%{name} membuang status oleh %{target}"
+        disable_2fa_user: "%{name} melumpuhkan keperluan dua faktor untuk pengguna %{target}"
+        disable_custom_emoji: "%{name} melumpuhkan emoji %{target}"
+        disable_user: "%{name} melumpuhkan log masuk untuk pengguna %{target}"
+        enable_custom_emoji: "%{name} membolehkan emoji %{target}"
+        enable_user: "%{name} membolehkan log masuk untuk pengguna %{target}"
+        memorialize_account: "%{name} menukarkan akaun %{target} menjadi halaman peringatan"
+        promote_user: "%{name} menaikkan pangkat pengguna %{target}"
+        remove_avatar_user: "%{name} membuang avatar pengguna %{target}"
+        reopen_report: "%{name} membuka semula laporan %{target}"
+        reset_password_user: "%{name} set semula kata laluan pengguna %{target}"
+        resolve_report: "%{name} menyelesaikan laporan %{target}"
+        silence_account: "%{name} menyenyapkan akaun %{target}"
+        suspend_account: "%{name} menggantung akaun %{target}"
+        unassigned_report: "%{name} menyahtugaskan laporan %{target}"
+        unsilence_account: "%{name} menyahsenyapkan akaun %{target}"
+        unsuspend_account: "%{name} menyahgantungkan akaun %{target}"
+        update_custom_emoji: "%{name} mengemaskini emoji %{target}"
+        update_status: "%{name} mengemaskini status oleh %{target}"
+      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
+      created_msg: Emoji berjaya dicipta!
+      delete: Padam
+      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
+      listed: Disenaraikan
+      new:
+        title: Tambah emoji sendiri baru
+      overwrite: Tulis ganti
+      shortcode: Kod pendek
+      shortcode_hint: Sekurang-kurangnya 2 aksara, hanya aksara angka abjad dan garis bawah
+      title: Emoji sendiri
+      unlisted: Tidak disenaraikan
+      update_failed_msg: Tidak boleh mengemaskini emoji tersebut
+      updated_msg: Emoji berjaya dikemaskini!
+      upload: Muat naik
+    dashboard:
+      backlog: tugasan tunggakan
+      config: Tatarajah
+      feature_deletions: Pemadaman akaun
+      feature_invites: Pautan undangan
+      feature_registrations: Pendaftaran
+      feature_relay: Geganti persekutuan
+      features: Ciri-ciri
+      hidden_service: Persekutuan dengan perkhidmatan tersembunyi
+      open_reports: laporan belum selesai
+      recent_users: Pengguna terbaru
+      search: Carian teks penuh
+      single_user_mode: Mod pengguna tunggal
+      software: Perisian
+      space: Kegunaan ruang
+      title: Papan pemuka
+      total_users: pengguna keseluruhannya
+      trends: Trend
+      week_interactions: interaksi minggu ini
+      week_users_active: aktif minggu ini
+      week_users_new: pengguna minggu ini
+    domain_blocks:
+      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.
+        severity:
+          desc_html: "<strong>Senyapkan</strong> akan membuatkan hantaran akaun tidak kelihatan kepada sesiapa yang tidak mengikut mereka. <strong>Gantungkan</strong> akan membuang semua kandungan, media, dan data profil akaun tersebut. Gunakan <strong>Tiada</strong> jika anda hanya ingin menolak fail media."
+          noop: Tiada
+          silence: Senyapkan
+          suspend: Gantungkan
+        title: Sekatan domain baru
+      reject_media: Tolak fail media
+      reject_media_hint: Buang fail media yang disimpan di sini dan menolak sebarang muat turun pada masa depan. Tidak berkaitan dengan penggantungan
+      reject_reports: Tolak laporan
+      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
+          suspend: Buang penggantungan semua akaun sedia ada daripada domain ini
+        title: Buang sekatan domain %{domain}
+        undo: Buang
+      undo: Buang
+    email_domain_blocks:
+      add_new: Tambah
+      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
+      title: Senarai hitam emel
+    instances:
+      title: Tika diketahui
+    invites:
+      deactivate_all: Nyahaktifkan semua
+      filter:
+        all: Semua
+        available: Tersedia
+        expired: Tamat tempoh
+        title: Tapis
+      title: Undangan
+    relays:
+      add_new: Tambah geganti baru
+      delete: Padam
+      description_html: "<strong>Geganti persekutuan</strong> ialah pelayan perantara yang saling menukar toot awam dalam jumlah yang banyak di antara pelayan yang melanggan ia dan menerbitkan kepada ia. <strong>Ia boleh bantu pelayan kecil dan sederhana untuk menemui kandungan daripada dunia persekutuan Mastodon</strong>, yang mana jika tidak digunakan akan memerlukan pengguna tempatan mengikut orang lain di pelayan jarak jauh secara manual."
+      disable: Lumpuhkan
+      disabled: Dilumpuhkan
+      enable: Bolehkan
+      enable_hint: Apabila dibolehkan, pelayan anda akan melanggan kesemua toot awam daripada geganti ini, dan akan mula menghantar toot awam pelayan ini kepada ia.
+      enabled: Dibolehkan
+      inbox_url: URL geganti
+      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!
+      destroyed_msg: Nota laporan berjaya dipadam!
+    reports:
+      account:
+        note: nota
+        report: laporan
+      action_taken_by: Tindakan oleh
+      are_you_sure: Anda pasti?
+      assign_to_self: Berikan pada saya
+      assigned: Pengawal yang menerima
+      comment:
+        none: Tiada
+      created_at: Dilaporkan
+      mark_as_resolved: Tanda sebagai sudah selesai
+      mark_as_unresolved: Tanda sebagai belum selesai
+      notes:
+        create: Tambah nota
+        create_and_resolve: Selesaikan dengan nota
+        placeholder: Terangkan tindakan apa yang telah diambil, atau sebarang kemas kini lain yang berkaitan...
+  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...
+  notification_mailer:
+    digest:
+      title: Ketika anda tiada di sini...
+  users:
+    follow_limit_reached: Anda tidak boleh mengikut lebih daripada %{limit} orang
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 2704ce02075bf8bf9917950f3629b27e10546254..dd23304fe0ae8fa69749548c4d140f0e56d0e4c9 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -5,13 +5,13 @@ nl:
     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
     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.
     contact: Contact
     contact_missing: Niet ingesteld
     contact_unavailable: n.v.t
-    description_headline: Wat is %{domain}?
-    domain_count_after: andere servers
-    domain_count_before: Verbonden met
+    documentation: Documentatie
     extended_description_html: |
       <h3>Een goede plek voor richtlijnen</h3>
       <p>De uitgebreide omschrijving is nog niet ingevuld.</p>
@@ -28,25 +28,41 @@ nl:
     hosted_on: Mastodon op %{domain}
     learn_more: Meer leren
     other_instances: Andere servers
+    privacy_policy: Privacybeleid
     source_code: Broncode
-    status_count_after: toots
+    status_count_after:
+      one: toot
+      other: toots
     status_count_before: Zij schreven
-    user_count_after: gebruikers
+    terms: Gebruiksvoorwaarden
+    user_count_after:
+      one: gebruiker
+      other: gebruikers
     user_count_before: Thuisbasis van
     what_is_mastodon: Wat is Mastodon?
   accounts:
+    choices_html: 'Aanbevelingen van %{name}:'
     follow: Volgen
-    followers: Volgers
+    followers:
+      one: Volger
+      other: Volgers
     following: Volgend
+    joined: Geregistreerd in %{date}
+    last_active: laatst actief
+    link_verified_on: Eigendom van deze link is gecontroleerd op %{date}
     media: Media
     moved_html: "%{name} is verhuisd naar %{new_profile_link}:"
     network_hidden: Deze informatie is niet beschikbaar
     nothing_here: Hier is niets!
     people_followed_by: Mensen die %{name} volgen
     people_who_follow: Mensen die %{name} volgen
-    posts: Toots
+    pin_errors:
+      following: Je moet dit account wel al volgen, alvorens je het kan aanbevelen
+    posts:
+      one: Toot
+      other: Toots
+    posts_tab_heading: Toots
     posts_with_replies: Toots en reacties
-    remote_follow: Extern volgen
     reserved_username: Deze gebruikersnaam is gereserveerd
     roles:
       admin: Beheerder
@@ -54,6 +70,9 @@ nl:
       moderator: Moderator
     unfollow: Ontvolgen
   admin:
+    account_actions:
+      action: Actie uitvoeren
+      title: Moderatieactie op %{acct} uitvoeren
     account_moderation_notes:
       create: Laat een opmerking achter
       created_msg: Aanmaken van opmerking voor moderatoren geslaagd!
@@ -73,6 +92,7 @@ nl:
       confirm: Bevestigen
       confirmed: Bevestigd
       confirming: Bevestiging
+      deleted: Verwijderd
       demote: Degraderen
       disable: Uitschakelen
       disable_two_factor_authentication: 2FA uitschakelen
@@ -81,15 +101,18 @@ nl:
       domain: Domein
       edit: Bewerken
       email: E-mail
-      email_status: E-mail Status
+      email_status: E-mailstatus
       enable: Inschakelen
       enabled: Ingeschakeld
       feed_url: Feed-URL
       followers: Volgers
       followers_url: Volgers-URL
       follows: Volgt
+      header: Omslagfoto
       inbox_url: Inbox-URL
+      invited_by: Uitgenodigd door
       ip: IP
+      joined: Geregistreerd in
       location:
         all: Alles
         local: Lokaal
@@ -99,6 +122,7 @@ nl:
       media_attachments: Mediabijlagen
       memorialize: In gedenkpagina veranderen
       moderation:
+        active: Actief
         all: Alles
         silenced: Genegeerd
         suspended: Opgeschort
@@ -106,20 +130,18 @@ nl:
       moderation_notes: Opmerkingen voor moderatoren
       most_recent_activity: Laatst actief
       most_recent_ip: Laatst gebruikt IP-adres
+      no_limits_imposed: Geen limieten ingesteld
       not_subscribed: Niet geabonneerd
-      order:
-        alphabetic: Alfabetisch
-        most_recent: Meest recent
-        title: Sorteren
       outbox_url: Outbox-URL
-      perform_full_suspension: Volledig opschorten
+      perform_full_suspension: Opschorten
       profile_url: Profiel-URL
       promote: Promoveren
       protocol: Protocol
       public: Openbaar
       push_subscription_expires: PuSH-abonnement verloopt op
-      redownload: Avatar vernieuwen
+      redownload: Profiel vernieuwen
       remove_avatar: Avatar verwijderen
+      remove_header: Omslagfoto verwijderen
       resend_confirmation:
         already_confirmed: Deze gebruiker is al bevestigd
         send: Verzend bevestigingsmail opnieuw
@@ -137,49 +159,54 @@ nl:
       search: Zoeken
       shared_inbox_url: Gedeelde inbox-URL
       show:
-        created_reports: Toots door dit account gerapporteerd
-        report: gerapporteerd
-        targeted_reports: Toots van dit account gerapporteerd
+        created_reports: Aangemaakte rapportages
+        targeted_reports: Door anderen gerapporteerd
       silence: Negeren
+      silenced: Genegeerd
       statuses: Toots
       subscribe: Abonneren
+      suspended: Opgeschort
       title: Accounts
       unconfirmed_email: Onbevestigd e-mailadres
       undo_silenced: Niet langer negeren
       undo_suspension: Niet langer opschorten
       unsubscribe: Opzeggen
       username: Gebruikersnaam
+      warn: Waarschuwen
       web: Webapp
     action_logs:
       actions:
-        assigned_to_self_report: "%{name} heeft gerapporteerde toot %{target} aan zichzelf toegewezen"
+        assigned_to_self_report: "%{name} heeft rapportage %{target} aan zichzelf toegewezen"
         change_email_user: "%{name} veranderde het e-mailadres van gebruiker %{target}"
         confirm_user: E-mailadres van gebruiker %{target} is door %{name} bevestigd
+        create_account_warning: "%{name} verzond een waarschuwing naar %{target}"
         create_custom_emoji: Nieuwe emoji %{target} is door %{name} geüpload
         create_domain_block: Domein %{target} is door %{name} geblokkeerd
         create_email_domain_block: E-maildomein %{target} is door %{name} op de zwarte lijst geplaatst
         demote_user: Gebruiker %{target} is door %{name} gedegradeerd
+        destroy_custom_emoji: "%{name} verwijderde emoji %{target}"
         destroy_domain_block: Domein %{target} is door %{name} gedeblokkeerd
         destroy_email_domain_block: E-maildomein %{target} is door %{name} op de witte lijst geplaatst
         destroy_status: Toot van %{target} is door %{name} verwijderd
         disable_2fa_user: Vereisten tweestapsverificatie van %{target} zijn door %{name} uitgeschakeld
         disable_custom_emoji: Emoji %{target} is door %{name} uitgeschakeld
-        disable_user: Aanmelden voor %{target} is door %{name} uitgeschakeld
+        disable_user: Inloggen voor %{target} is door %{name} uitgeschakeld
         enable_custom_emoji: Emoji %{target} is door %{name} ingeschakeld
         enable_user: Inloggen voor %{target} is door %{name} ingeschakeld
         memorialize_account: Account %{target} is door %{name} in een gedenkpagina veranderd
         promote_user: Gebruiker %{target} is door %{name} gepromoveerd
         remove_avatar_user: "%{name} verwijderde de avatar van %{target}"
-        reopen_report: "%{name} heeft gerapporteerde toot %{target} heropend"
+        reopen_report: "%{name} heeft rapportage %{target} heropend"
         reset_password_user: Wachtwoord van gebruiker %{target} is door %{name} opnieuw ingesteld
-        resolve_report: "%{name} heeft gerapporteerde toot %{target} opgelost"
+        resolve_report: "%{name} heeft rapportage %{target} opgelost"
         silence_account: Account %{target} is door %{name} genegeerd
         suspend_account: Account %{target} is door %{name} opgeschort
-        unassigned_report: "%{name} heeft het toewijzen van gerapporteerde toot %{target} ongedaan gemaakt"
+        unassigned_report: "%{name} heeft het toewijzen van rapportage %{target} ongedaan gemaakt"
         unsilence_account: Negeren van account %{target} is door %{name} opgeheven
         unsuspend_account: Opschorten van account %{target} is door %{name} opgeheven
         update_custom_emoji: Emoji %{target} is door %{name} bijgewerkt
         update_status: De toots van %{target} zijn door %{name} bijgewerkt
+      deleted_status: "(verwijderde toot}"
       title: Auditlog
     custom_emojis:
       by_domain: Domein
@@ -206,8 +233,30 @@ nl:
       update_failed_msg: Deze emoji kon niet worden bijgewerkt
       updated_msg: Bijwerken van emoji is geslaagd!
       upload: Uploaden
+    dashboard:
+      backlog: achterstallige taken
+      config: Configuratie
+      feature_deletions: Verwijderen van account
+      feature_invites: Uitnodigingen
+      feature_profile_directory: Gebruikersgids
+      feature_registrations: Registraties
+      feature_relay: Federatierelay
+      features: Functies
+      hidden_service: Federatie met verborgen diensten
+      open_reports: onopgeloste rapportages
+      recent_users: Recente gebruikers
+      search: In volledige tekst zoeken
+      single_user_mode: Modus voor één gebruiker
+      software: Software
+      space: Ruimtegebruik
+      title: Dashboard
+      total_users: gebruikers in totaal
+      trends: Trends
+      week_interactions: interacties deze week
+      week_users_active: actieve gebruikers deze week
+      week_users_new: nieuwe gebruikers deze week
     domain_blocks:
-      add_new: Nieuwe toevoegen
+      add_new: Nieuwe domeinblokkade toevoegen
       created_msg: Domeinblokkade wordt nu verwerkt
       destroyed_msg: Domeinblokkade is ongedaan gemaakt
       domain: Domein
@@ -220,13 +269,15 @@ nl:
           silence: Negeren
           suspend: Opschorten
         title: Nieuwe domeinblokkade
-      reject_media: Mediabestanden verwerpen
+      reject_media: Mediabestanden weigeren
       reject_media_hint: Verwijderd lokaal opgeslagen mediabestanden en weigert deze in de toekomst te downloaden. Irrelevant voor opgeschorte domeinen
-      severities:
-        noop: Geen
-        silence: Negeren
-        suspend: Opschorten
-      severity: Zwaarte
+      reject_reports: Rapportages weigeren
+      reject_reports_hint: Alle rapportages die vanaf dit domein komen negeren. Irrelevant voor opgeschorte domeinen
+      rejecting_media: mediabestanden worden geweigerd
+      rejecting_reports: rapportages worden geweigerd
+      severity:
+        silence: genegeerd
+        suspend: opgeschort
       show:
         affected_accounts:
           one: Eén account in de database aangepast
@@ -236,8 +287,7 @@ nl:
           suspend: Alle opgeschorte accounts van dit domein niet langer opschorten
         title: Domeinblokkade voor %{domain} ongedaan maken
         undo: Ongedaan maken
-      title: Domeinblokkades
-      undo: Ongedaan maken
+      undo: domeinblokkade ongedaan maken
     email_domain_blocks:
       add_new: Nieuwe toevoegen
       created_msg: Blokkeren e-maildomein geslaagd
@@ -248,26 +298,54 @@ nl:
         create: Blokkeren
         title: Nieuw e-maildomein blokkeren
       title: E-maildomeinen blokkeren
+    followers:
+      back_to_account: Terug naar account
+      title: Volgers van %{acct}
     instances:
-      account_count: Bekende accounts
-      domain_name: Domein
-      reset: Opnieuw
-      search: Zoeken
-      title: Bekende servers
+      delivery_available: Bezorging is mogelijk
+      known_accounts:
+        one: "%{count} bekend account"
+        other: "%{count} bekende accounts"
+      moderation:
+        all: Alles
+        limited: Beperkt
+        title: Moderatie
+      title: Andere domeinen
+      total_blocked_by_us: Door ons geblokkeerd
+      total_followed_by_them: Door hun gevolgd
+      total_followed_by_us: Door ons gevolgd
+      total_reported: Rapportages over hun
+      total_storage: Mediabijlagen
     invites:
+      deactivate_all: Alles deactiveren
       filter:
         all: Alles
         available: Beschikbaar
         expired: Verlopen
         title: Filter
       title: Uitnodigingen
+    relays:
+      add_new: Nieuwe relayserver toevoegen
+      delete: Verwijderen
+      description_html: Een <strong>federatierelay</strong> is een tussenliggende server die grote hoeveelheden openbare toots uitwisselt tussen servers die zich hierop hebben geabonneerd. <strong>Het kan kleine en middelgrote servers helpen om content uit de fediverse te ontdekken</strong>, waarvoor anders lokale gebruikers handmatig mensen van externe servers moeten volgen.
+      disable: Uitschakelen
+      disabled: Uitgeschakeld
+      enable: Inschakelen
+      enable_hint: Eenmaal ingeschakeld gaat jouw server zich op alle openbare toots van deze relayserver abonneren en stuurt het de openbare toots van jouw server naar de relayserver.
+      enabled: Ingeschakeld
+      inbox_url: Relay-URL
+      pending: Aan het wachten op toestemming van de relayserver
+      save_and_enable: Opslaan en inschakelen
+      setup: Een verbinding met een relayserver maken
+      status: Status
+      title: Relayservers
     report_notes:
-      created_msg: Opmerking bij gerapporteerde toot succesvol aangemaakt!
-      destroyed_msg: Opmerking bij gerapporteerde toot succesvol verwijderd!
+      created_msg: Opmerking bij rapportage succesvol aangemaakt!
+      destroyed_msg: Opmerking bij rapportage succesvol verwijderd!
     reports:
       account:
         note: opmerking
-        report: gerapporteerde toot
+        report: rapportage
       action_taken_by: Actie uitgevoerd door
       are_you_sure: Weet je het zeker?
       assign_to_self: Aan mij toewijzen
@@ -275,7 +353,6 @@ nl:
       comment:
         none: Geen
       created_at: Gerapporteerd op
-      id: ID
       mark_as_resolved: Markeer als opgelost
       mark_as_unresolved: Markeer als onopgelost
       notes:
@@ -284,22 +361,17 @@ nl:
         create_and_unresolve: Heropenen met opmerking
         delete: Verwijderen
         placeholder: Beschrijf welke acties zijn ondernomen of andere gerelateerde opmerkingen…
-      reopen: Gerapporteerde toot heropenen
-      report: 'Gerapporteerde toot #%{id}'
-      report_contents: Inhoud
+      reopen: Rapportage heropenen
+      report: 'Rapportage #%{id}'
       reported_account: Gerapporteerde account
       reported_by: Gerapporteerd door
       resolved: Opgelost
-      resolved_msg: Gerapporteerde toot succesvol opgelost!
-      silence_account: Account negeren
+      resolved_msg: Rapportage succesvol opgelost!
       status: Toot
-      suspend_account: Account opschorten
-      target: Gerapporteerde account
-      title: Gerapporteerde toots
+      title: Rapportages
       unassign: Niet langer toewijzen
       unresolved: Onopgelost
       updated_at: Bijgewerkt
-      view: Weergeven
     settings:
       activity_api_enabled:
         desc_html: Wekelijks overzicht van de hoeveelheid lokale toots, actieve gebruikers en nieuwe registraties
@@ -310,15 +382,24 @@ nl:
       contact_information:
         email: Vul een openbaar gebruikt e-mailadres in
         username: Vul een gebruikersnaam in
+      custom_css:
+        desc_html: Het uiterlijk van deze server met CSS aanpassen
+        title: Aangepaste CSS
       hero:
         desc_html: Wordt op de voorpagina getoond. Tenminste 600x100px aanbevolen. Wanneer dit niet is ingesteld wordt de thumbnail van de Mastodonserver getoond
         title: Hero-afbeelding
+      mascot:
+        desc_html: Wordt op meerdere pagina's weergegeven. Tenminste 293×205px aanbevolen. Wanneer dit niet is ingesteld wordt de standaardmascotte getoond
+        title: Mascotte-afbeelding
       peers_api_enabled:
         desc_html: Domeinnamen die deze server in de fediverse is tegengekomen
         title: Lijst van bekende servers publiceren
       preview_sensitive_media:
         desc_html: Linkvoorvertoningen op andere websites hebben een thumbnail, zelfs als een afbeelding of video als gevoelig is gemarkeerd
         title: Gevoelige afbeeldingen en video's in OpenGraph-voorvertoningen tonen
+      profile_directory:
+        desc_html: Gebruikers toestaan om vindbaar te zijn
+        title: Gebruikersgids inschakelen
       registrations:
         closed_message:
           desc_html: Wordt op de voorpagina weergegeven wanneer registratie van nieuwe accounts is uitgeschakeld<br>En ook hier kan je HTML gebruiken
@@ -339,11 +420,14 @@ nl:
         desc_html: Medewerkersbadge op profielpagina tonen
         title: Medewerkersbadge tonen
       site_description:
-        desc_html: Dit wordt als een alinea op de voorpagina getoond en gebruikt als meta-tag in de paginabron.<br/>Je kan HTML gebruiken, zoals <code>&lt;a&gt;</code> en <code>&lt;em&gt;</code>.
+        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
       site_description_extended:
         desc_html: Wordt op de uitgebreide informatiepagina weergegeven<br>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
       site_terms:
         desc_html: Je kan hier jouw eigen privacybeleid, gebruiksvoorwaarden en ander juridisch jargon kwijt. Je kan HTML gebruiken
         title: Aangepaste gebruiksvoorwaarden
@@ -365,6 +449,7 @@ nl:
       media:
         title: Media
       no_media: Geen media
+      no_status_selected: Er werden geen toots gewijzigd, omdat er geen enkele werd geselecteerd
       title: Toots van account
       with_media: Met media
     subscriptions:
@@ -374,12 +459,26 @@ nl:
       last_delivery: Laatste bezorging
       title: WebSub
       topic: Account
+    tags:
+      accounts: Accounts
+      hidden: Verborgen
+      hide: Niet in gebruikersgids tonen
+      name: Hashtag
+      title: Hashtags
+      unhide: In gebruikersgids tonen
+      visible: Zichtbaar
     title: Beheer
+    warning_presets:
+      add_new: Nieuwe toevoegen
+      delete: Verwijderen
+      edit: Bewerken
+      edit_preset: Voorinstelling van waarschuwing bewerken
+      title: Voorinstellingen van waarschuwingen beheren
   admin_mailer:
     new_report:
       body: "%{reporter} heeft %{target} gerapporteerd"
       body_remote: Iemand van %{domain} heeft %{target} gerapporteerd
-      subject: Nieuwe toots gerapporteerd op %{instance} (#%{id})
+      subject: Nieuwe rapportage op %{instance} (#%{id})
   application_mailer:
     notification_preferences: E-mailvoorkeuren wijzigen
     salutation: "%{name},"
@@ -404,12 +503,12 @@ nl:
     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.
-    login: Aanmelden
-    logout: Afmelden
-    migrate_account: Naar een andere account verhuizen
+    login: Inloggen
+    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 aanmelden met
+    or_log_in_with: Of inloggen met
     providers:
       cas: CAS
       saml: SAML
@@ -452,6 +551,16 @@ nl:
     success_msg: Jouw account is succesvol verwijderd
     warning_html: We kunnen alleen garanderen dat jouw gegevens op deze server worden verwijderd. Berichten (toots), incl. media, die veel zijn gedeeld laten mogelijk sporen achter. Offline servers en servers die niet meer op jouw updates zijn geabonneerd zullen niet hun databases updaten.
     warning_title: Verwijdering gegevens op andere servers
+  directories:
+    directory: Gebruikersgids
+    enabled: Je staat momenteel in de gebruikersgids vermeldt.
+    enabled_but_waiting: Je hebt er voor gekozen om in de gebruikersgids te worden vermeldt, maar je hebt daarvoor nog niet het minimaal aantal volgers (%{min_followers}).
+    explanation: Ontdek gebruikers aan de hand van hun interesses
+    explore_mastodon: "%{title} verkennen"
+    how_to_enable: Je geeft momenteel geen toestemming om in de gebruikersgids te worden vermeldt. Je kunt hieronder toestemming geven. Gebruik hashtags in de tekst van jouw bio, om onder bepaalde hashtags te worden vermeldt!
+    people:
+      one: "%{count} gebruikers"
+      other: "%{count} gebruikers"
   errors:
     '403': Jij hebt geen toestemming om deze pagina te bekijken.
     '404': De pagina waarnaar jij op zoek bent bestaat niet.
@@ -463,7 +572,7 @@ nl:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">Mastodon-app</a> zoeken voor jouw platform.
+    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.
   exports:
     archive_takeout:
       date: Datum
@@ -474,7 +583,9 @@ nl:
       size: Omvang
     blocks: Jij blokkeert
     csv: CSV
+    domain_blocks: Domeinblokkades
     follows: Jij volgt
+    lists: Lijsten
     mutes: Jij negeert
     storage: Mediaopslag
   filters:
@@ -492,7 +603,7 @@ nl:
       delete: Verwijderen
       title: Filters
     new:
-      title: Nieuwe filter toevoegen
+      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.
@@ -505,9 +616,13 @@ nl:
     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:
     changes_saved_msg: Wijzigingen succesvol opgeslagen!
-    powered_by: wordt mogelijk gemaakt door %{link}
+    copy: Kopiëren
     save_changes: Wijzigingen opslaan
     validation_errors:
       one: Er is iets niet helemaal goed! Bekijk onderstaande fout
@@ -543,8 +658,6 @@ nl:
       expires_at: Verloopt op
       uses: Aantal keer te gebruiken
     title: Mensen uitnodigen
-  landing_strip_html: "<strong>%{name}</strong> is een gebruiker op %{link_to_root_path}. Je kunt deze volgen en ermee communiceren als je op Mastodon (of ergens anders in de fediverse) een account hebt."
-  landing_strip_signup_html: Als je dat niet hebt, kun je je <a href="%{sign_up_path}">hier registreren</a>.
   lists:
     errors:
       limit: Je hebt het maximaal aantal lijsten bereikt
@@ -572,8 +685,8 @@ nl:
         other: "%{count} nieuwe meldingen sinds jouw laatste bezoek \U0001F418"
       title: Tijdens jouw afwezigheid...
     favourite:
-      body: 'Jouw toot werd door %{name} als favoriet gemarkeerd:'
-      subject: "%{name} markeerde jouw toot als favoriet"
+      body: 'Jouw toot werd door %{name} aan hun favorieten toegevoegd:'
+      subject: "%{name} voegde jouw toot als favoriet toe"
       title: Nieuwe favoriet
     follow:
       body: "%{name} volgt jou nu!"
@@ -616,15 +729,30 @@ nl:
     publishing: Publiceren
     web: Webapp
   remote_follow:
-    acct: Geef jouw account@domein.tld op waarvandaan je wilt volgen
+    acct: Geef jouw account@domein op die je wilt gebruiken
     missing_resource: Kon vereiste doorverwijzings-URL voor jouw account niet vinden
     no_account_html: Heb je geen account? Je kunt er <a href='%{sign_up_path}' target='_blank'>hier een registreren</a>
-    proceed: Ga door om te volgen
+    proceed: Ga verder om te volgen
     prompt: 'Jij gaat volgen:'
+    reason_html: "<strong> Waarom is deze extra stap nodig? </strong> <code>%{instance}</code> is wellicht niet de server waarop jij je geregistreerd hebt. We verwijzen je eerst door naar jouw eigen server."
+  remote_interaction:
+    favourite:
+      proceed: Doorgaan met toevoegen aan jouw favorieten
+      prompt: 'Je wilt de volgende toot aan jouw favorieten toevoegen:'
+    reblog:
+      proceed: Doorgaan met boosten
+      prompt: 'Je wilt de volgende toot boosten:'
+    reply:
+      proceed: Doorgaan met reageren
+      prompt: 'Je wilt op de volgende toot reageren:'
   remote_unfollow:
     error: Fout
     title: Titel
     unfollowed: Ontvolgd
+  scheduled_statuses:
+    over_daily_limit: Je hebt de limiet van %{limit} in te plannen toots voor die dag overschreden
+    over_total_limit: Je hebt de limiet van %{limit} in te plannen toots overschreden
+    too_soon: De datum voor de ingeplande toot moet in de toekomst liggen
   sessions:
     activity: Laatst actief
     browser: Webbrowser
@@ -704,6 +832,7 @@ nl:
       private: Alleen openbare toots kunnen worden vastgezet
       reblog: Een boost kan niet worden vastgezet
     show_more: Meer tonen
+    sign_in_to_participate: Meld je aan om aan dit gesprek mee te doen
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Alleen volgers
@@ -713,7 +842,6 @@ nl:
       unlisted: Minder openbaar
       unlisted_long: Aan iedereen tonen, maar niet op openbare tijdlijnen
   stream_entries:
-    click_to_show: Klik om te tonen
     pinned: Vastgemaakte toot
     reblogged: boostte
     sensitive_content: Gevoelige inhoud
@@ -799,7 +927,7 @@ nl:
       <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"
+    title: Gebruiksvoorwaarden en privacybeleid van %{instance}
   themes:
     contrast: Hoog contrast
     default: Mastodon
@@ -807,17 +935,18 @@ nl:
   time:
     formats:
       default: "%d %B %Y om %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Voer de code in die door de authenticatie-app gegenereerd is
-    description_html: Na het instellen van <strong>tweestapsverificatie</strong>, kun jij je alleen aanmelden als je jouw mobiele telefoon bij je hebt. Hiermee genereer je namelijk de in te voeren aanmeldcode.
+    description_html: Na het instellen van <strong>tweestapsverificatie</strong>, kun je alleen inloggen als je jouw mobiele telefoon bij je hebt. Hiermee genereer je namelijk de in te voeren aanmeldcode.
     disable: Uitschakelen
     enable: Inschakelen
     enabled: Tweestapsverificatie is ingeschakeld
     enabled_success: Inschakelen tweestapsverificatie geslaagd
     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 aanmelden moet invoeren."
+    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: Hieronder vind je de geheime code in platte tekst. Voor het geval je de QR-code niet kunt scannen en het handmatig moet invoeren.
+    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.
     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.
@@ -828,6 +957,22 @@ nl:
       explanation: Je hebt een volledige back-up van jouw Mastodon-account opgevraagd. Het staat nu klaar om te worden gedownload!
       subject: Jouw archief staat klaar om te worden gedownload
       title: Archief ophalen
+    warning:
+      explanation:
+        disable: Zolang jouw account is bevroren blijven jouw accountgegevens intact, maar kun je geen handelingen uitvoeren totdat het account is vrijgegeven.
+        silence: Zolang jouw account wordt beperkt, kunnen alleen mensen die jou al volgen jouw toots op deze server zien. Tevens ben je niet zichtbaar in meldingen, gesprekken en op openbare tijdlijnen. Anderen kunnen je echter wel handmatig volgen.
+        suspend: Jouw account is opgeschort. Jouw toots en geüploade media zijn onomkeerbaar van deze server verwijderd, en ook o.a. van de servers waar jij volgers had.
+      review_server_policies: Serverbeleid bekijken
+      subject:
+        disable: Jouw account %{acct} is bevroren
+        none: Waarschuwing voor %{acct}
+        silence: Jouw account %{acct} is nu beperkt
+        suspend: Jouw account %{acct} is opgeschort
+      title:
+        disable: Account bevroren
+        none: Waarschuwing
+        silence: Account beperkt
+        suspend: Account opgeschort
     welcome:
       edit_profile_action: Profiel instellen
       edit_profile_step: Je kunt jouw profiel aanpassen door een avatar (profielfoto) en omslagfoto te uploaden, jouw weergavenaam in te stellen en iets over jezelf te vertellen. Wanneer je nieuwe volgers eerst wilt goedkeuren, kun je jouw account besloten maken.
@@ -839,7 +984,6 @@ nl:
       review_preferences_action: Instellingen veranderen
       review_preferences_step: Zorg dat je jouw instellingen naloopt, zoals welke e-mails je wilt ontvangen of voor wie jouw berichten standaard zichtbaar moeten zijn. Wanneer je geen last hebt van bewegende beelden, kun je het afspelen van geanimeerde GIF's inschakelen.
       subject: Welkom op Mastodon
-      tip_bridge_html: Wanneer je hiervoor op Twitter zat, kun je jouw vrienden op Mastodon vinden door gebruik te maken van de <a href="%{bridge_url}">bridge-app</a>. Het werkt echter alleen wanneer zij ook deze bridge-app hebben gebruikt!
       tip_federated_timeline: De globale tijdlijn toont berichten in het Mastodonnetwerk. Het bevat echter alleen berichten van mensen waar jouw buren mee zijn verbonden, dus het is niet compleet.
       tip_following: Je volgt standaard de beheerder(s) van jouw Mastodonserver. Bekijk de lokale en de globale tijdlijnen om meer interessante mensen te vinden.
       tip_local_timeline: De lokale tijdlijn toont berichten van mensen op %{instance}. Dit zijn jouw naaste buren!
@@ -847,8 +991,12 @@ nl:
       tips: Tips
       title: Welkom aan boord %{name}!
   users:
+    follow_limit_reached: Je kunt niet meer dan %{limit} accounts volgen
     invalid_email: E-mailadres is ongeldig
     invalid_otp_token: Ongeldige tweestaps-aanmeldcode
     otp_lost_help_html: Als je toegang tot beiden kwijt bent geraakt, neem dan contact op via %{email}
     seamless_external_login: Je bent ingelogd via een externe dienst, daarom zijn wachtwoorden en e-mailinstellingen niet beschikbaar.
     signed_in_as: 'Ingelogd als:'
+  verification:
+    explanation_html: 'Je kunt <strong>jezelf verifiëren als de eigenaar van de links in de metadata van jouw profiel</strong>. Hiervoor moet op de gelinkte website een link terug naar jouw Mastodonprofiel staan. Deze link <strong>moet</strong> het <code>rel="me"</code>-attribuut bevatten. De omschrijving van de link maakt niet uit. Hier is een voorbeeld:'
+    verification: Verificatie
diff --git a/config/locales/no.yml b/config/locales/no.yml
index 7ce04f5108e233abca032dab69fd9de7104ffc03..5a85a7561198100a71c54f6b1669d53cdf1d53cd 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -8,9 +8,6 @@
     contact: Kontakt
     contact_missing: Ikke innstilt
     contact_unavailable: Ikke tilgjengelig
-    description_headline: Hva er %{domain}?
-    domain_count_after: andre instanser
-    domain_count_before: Koblet til
     extended_description_html: |
       <h3>En god plassering for regler</h3>
       <p>En utvidet beskrivelse er ikke satt opp ennå.</p>
@@ -44,7 +41,6 @@
     people_who_follow: Folk som følger %{name}
     posts: Poster
     posts_with_replies: Tuter med svar
-    remote_follow: Følg fra andre instanser
     reserved_username: Brukernavnet er reservert
     roles:
       admin: Admin
@@ -96,10 +92,6 @@
       most_recent_activity: Nyligste aktivitet
       most_recent_ip: Nyligste IP
       not_subscribed: Ikke abonnért
-      order:
-        alphabetic: Alfabetisk
-        most_recent: Nyligst
-        title: Rekkefølge
       outbox_url: Utboks URL
       perform_full_suspension: Utfør full utvisning
       profile_url: Profil-URL
@@ -126,7 +118,6 @@
       shared_inbox_url: Delt Innboks URL
       show:
         created_reports: Rapporter laget av denne kontoen
-        report: rapport
         targeted_reports: Rapporter laget om denne kontoen
       silence: MÃ¥lbind
       statuses: Statuser
@@ -204,11 +195,6 @@
         title: Ny domeneblokkering
       reject_media: Avvis mediefiler
       reject_media_hint: Fjerner lokalt lagrede mediefiler og nekter å laste dem ned i fremtiden. Irrelevant for utvisninger
-      severities:
-        noop: Ingen
-        silence: MÃ¥lbind
-        suspend: Utvis
-      severity: Alvorlighet
       show:
         affected_accounts:
           one: En konto i databasen påvirket
@@ -218,7 +204,6 @@
           suspend: Avutvis alle eksisterende kontoer fra dette domenet
         title: Angre domeneblokkering for %{domain}
         undo: Angre
-      title: Domeneblokkeringer
       undo: Angre
     email_domain_blocks:
       add_new: Lag ny
@@ -231,10 +216,6 @@
         title: Ny blokkeringsoppføring av e-postdomene
       title: Blokkering av e-postdomene
     instances:
-      account_count: Kjente kontoer
-      domain_name: Domene
-      reset: Tilbakestill
-      search: Søk
       title: Kjente instanser
     invites:
       filter:
@@ -248,20 +229,14 @@
       are_you_sure: Er du sikker?
       comment:
         none: Ingen
-      id: ID
       mark_as_resolved: Merk som løst
       report: 'Rapportér #%{id}'
-      report_contents: Innhold
       reported_account: Rapportert konto
       reported_by: Rapportert av
       resolved: Løst
-      silence_account: MÃ¥lbind konto
       status: Status
-      suspend_account: Utvis konto
-      target: MÃ¥l
       title: Rapporter
       unresolved: Uløst
-      view: Vis
     settings:
       activity_api_enabled:
         desc_html: Antall lokale statusposter, aktive brukere og nye registreringer i ukentlige oppdelinger
@@ -406,7 +381,7 @@
     '500':
       content: Beklager men noe gikk galt ved vår ende.
       title: Denne siden er ikke korrekt
-    noscript_html: For å bruke Mastodon webapplikasjon må du aktivere JavaScript. Alternativt kan du forsøke en av de mange <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">integrerte appene</a> for Mastodon til din plattform.
+    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
@@ -427,7 +402,6 @@
     unlocked_warning_title: Din konto er ikke låst
   generic:
     changes_saved_msg: Vellykket lagring av endringer!
-    powered_by: drevet av %{link}
     save_changes: Lagre endringer
     validation_errors:
       one: Noe er ikke helt riktig ennå. Vennligst se etter en gang til
@@ -461,8 +435,6 @@
       expires_at: Utløper
       uses: Bruk
     title: Inviter personer
-  landing_strip_html: "<strong>%{name}</strong> er en bruker på %{link_to_root_path}. Du kan følge dem eller kommunisere med dem hvis du har en konto hvor som helst i fediverset."
-  landing_strip_signup_html: Hvis du ikke har en konto så kan du <a href="%{sign_up_path}">registrere deg her</a>.
   lists:
     errors:
       limit: Du har nådd det maksimale antall lister
@@ -610,7 +582,6 @@
       unlisted: Uoppført
       unlisted_long: Synlig for alle, men ikke på offentlige tidslinjer
   stream_entries:
-    click_to_show: Klikk for å vise
     pinned: Festet tut
     reblogged: fremhevde
     sensitive_content: Følsomt innhold
@@ -649,7 +620,6 @@
       review_preferences_action: Endre innstillinger
       review_preferences_step: Husk å justere dine innstillinger, som hvilke e-poster du ønsker å motta, eller hvor private du ønsker at dine poster skal være som standard. Hvis du ikke har bevegelsessyke kan du skru på automatisk avspilling av GIF-animasjoner.
       subject: Velkommen til Mastodon
-      tip_bridge_html: Hvis du kommer fra Twitter kan du finne dine venner på Mastodon ved å bruke en <a href="%{bridge_url}">bro app</a>. Men det fungerer kun dersom de også bruker bro-appen!
       tip_federated_timeline: Den forente tidslinjen blir konstant matet med meldinger fra Mastodon-nettverket. Men den inkluderer bare personer dine naboer abbonerer på, så den er ikke komplett.
       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!
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 8871da65322d720c673bc099495005de62ec6743..ef158074af9a92dae6102b52a8ae7354a197fa31 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -5,13 +5,13 @@ oc:
     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
+    apps: Aplicacions per mobil
     closed_registrations: Las inscripcions son clavadas pel moment sus aquesta instància.
     contact: Contacte
     contact_missing: Pas parametrat
     contact_unavailable: Pas disponible
-    description_headline: Qué es %{domain} ?
-    domain_count_after: autras instàncias
-    domain_count_before: Connectat a
+    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>
@@ -28,25 +28,41 @@ oc:
     hosted_on: Mastodon albergat sus %{domain}
     learn_more: Ne saber mai
     other_instances: Lista d’instàncias
+    privacy_policy: Politica de confidencialitat
     source_code: Còdi font
-    status_count_after: estatuts
+    status_count_after:
+      one: estatut
+      other: estatuts
     status_count_before: qu’an escrich
-    user_count_after: personas
+    terms: Condicions d’utilizacion
+    user_count_after:
+      one: utilizaire
+      other: utilizaires
     user_count_before: Ostal de
     what_is_mastodon: Qu’es Mastodon ?
   accounts:
+    choices_html: 'Recomandacions de %{name} :'
     follow: Sègre
-    followers: Seguidors
+    followers:
+      one: Seguidor
+      other: Seguidors
     following: Abonaments
+    joined: Arribèt en %{date}
+    last_active: darrièra activitat
+    link_verified_on: La proprietat d’aqueste ligam foguèt verificada lo %{date}
     media: Mèdias
     moved_html: "%{name} a mudat a %{new_profile_link} :"
     network_hidden: Aquesta informacion es pas disponibla
     nothing_here: I a pas res aquí !
     people_followed_by: Lo monde que %{name} sèc
     people_who_follow: Lo monde que sègon %{name}
-    posts: Tuts
+    pin_errors:
+      following: Vos cal d’en primièr sègre las personas que volètz promòure
+    posts:
+      one: Tut
+      other: Tuts
+    posts_tab_heading: Tuts
     posts_with_replies: Tuts e responsas
-    remote_follow: Sègre a distància
     reserved_username: Aqueste nom d’utilizaire es reservat
     roles:
       admin: Admin
@@ -54,6 +70,9 @@ oc:
       moderator: Moderador
     unfollow: Quitar de sègre
   admin:
+    account_actions:
+      action: Realizar una accion
+      title: Realizar una accion de moderacion sus %{acct}
     account_moderation_notes:
       create: Crear una nòta
       created_msg: Nòta de moderacion ben creada !
@@ -68,11 +87,12 @@ oc:
         current_email: Adreça actuala
         label: Cambiar d’adreça
         new_email: Novèla adreça
-        submit: Cambiar
+        submit: Cambiar l’adreça
         title: Cambiar l’adreça a %{username}
       confirm: Confirmar
       confirmed: Confirmat
       confirming: Confirmacion
+      deleted: Suprimits
       demote: Retrogradar
       disable: Desactivar
       disable_two_factor_authentication: Desactivar 2FA
@@ -88,49 +108,50 @@ oc:
       followers: Seguidors
       followers_url: URL dels seguidors
       follows: Abonaments
+      header: Bandièra
       inbox_url: URL de recepcion
+      invited_by: Convidat per
       ip: IP
+      joined: Venguèt
       location:
         all: Totes
         local: Locals
         remote: Alonhats
         title: Emplaçament
       login_status: Estat formulari de connexion
-      media_attachments: Mèdias ajustats
+      media_attachments: Mèdias enviats
       memorialize: Passar en memorial
       moderation:
-        all: Tot
-        silenced: Rescondut
-        suspended: Suspendut
+        active: Actius
+        all: Totes
+        silenced: Resconduts
+        suspended: Suspenduts
         title: Moderacion
       moderation_notes: Nòtas de moderacion
       most_recent_activity: Activitat mai recenta
       most_recent_ip: IP mai recenta
+      no_limits_imposed: Cap de limit impausat
       not_subscribed: Pas seguidor
-      order:
-        alphabetic: Alfabetic
-        most_recent: Mai recent
-        title: Ordre
       outbox_url: URL Outbox
-      perform_full_suspension: Botar en tren la suspension complèta
+      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 los avatars
+      redownload: Actualizar lo perfil
       remove_avatar: Supriir l’avatar
+      remove_header: Levar la bandièra
       resend_confirmation:
         already_confirmed: Aqueste utilizaire es ja confirmat
         send: Tornar mandar lo corrièl de confirmacion
-        success: Corrièl de confirmacion corrèctament mandat !
+        success: Corrièl de confirmacion corrèctament mandat !
       reset: Reïnicializar
       reset_password: Reïnicializar lo senhal
       resubscribe: Se tornar abonar
       role: Permissions
       roles:
         admin: Administrator
-        bot: Robòt
         moderator: Moderador
         staff: Personnal
         user: Uitlizaire
@@ -138,28 +159,32 @@ oc:
       search: Cercar
       shared_inbox_url: URL de recepcion partejada
       show:
-        created_reports: Rapòrts creat per aqueste compte
-        report: rapòrt
-        targeted_reports: Rapòrts faches tocant aqueste compte
+        created_reports: Senhalaments creats
+        targeted_reports: Senhalaments dels autres
       silence: Silenci
+      silenced: Rescondut
       statuses: Estatuts
       subscribe: S’abonar
+      suspended: Suspendut
       title: Comptes
       unconfirmed_email: Adreça pas confirmada
       undo_silenced: Levar lo silenci
       undo_suspension: Levar la suspension
       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}"
         change_email_user: "%{name} cambièt l’adreça de corrièl de %{target}"
         confirm_user: "%{name} confirmèt l’adreça a %{target}"
+        create_account_warning: "%{name} mandèt un avertiment a %{target}"
         create_custom_emoji: "%{name} mandèt un nòu emoji %{target}"
         create_domain_block: "%{name} bloquèt lo domeni %{target}"
         create_email_domain_block: "%{name} botèt a la lista nègra lo domeni de corrièl %{target}"
         demote_user: "%{name} retragradèt l‘utilizaire %{target}"
+        destroy_custom_emoji: "%{name} destruguèt l’emoji %{target}"
         destroy_domain_block: "%{name} desbloquèt lo domeni %{target}"
         destroy_email_domain_block: "%{name} botèt a la lista blanca lo domeni de corrièl %{target}"
         destroy_status: "%{name} levèt l‘estatut a %{target}"
@@ -181,6 +206,7 @@ oc:
         unsuspend_account: "%{name} restabliguèt lo compte a %{target}"
         update_custom_emoji: "%{name} metèt a jorn l’emoji %{target}"
         update_status: "%{name} metèt a jorn l’estatut a %{target}"
+      deleted_status: "(estatut suprimit)"
       title: Audit dels jornals
     custom_emojis:
       by_domain: Domeni
@@ -207,8 +233,30 @@ oc:
       update_failed_msg: Mesa a jorn de l’emoji fracasada
       updated_msg: Emoji ben mes a jorn !
       upload: Enviar
+    dashboard:
+      backlog: Accions en retard
+      config: Configuracion
+      feature_deletions: Supressions de comptes
+      feature_invites: Ligams convidat
+      feature_profile_directory: Annuari de perfils
+      feature_registrations: Inscripcions
+      feature_relay: Relai de federacion
+      features: Foncionalitats
+      hidden_service: Federacion amb servicis amagats
+      open_reports: Senhalaments dobèrts
+      recent_users: Utilizaires recents
+      search: Recèrca tèxte complèt
+      single_user_mode: Mòde sol utilizaire
+      software: Logicial
+      space: Utilizacion de l’espaci
+      title: Tablèu de bòrd
+      total_users: total dels utilizaires
+      trends: Tendéncias
+      week_interactions: interaccions aquesta setmana
+      week_users_active: actius aquesta setmana
+      week_users_new: utilizaires aquesta setmana
     domain_blocks:
-      add_new: Ajustar
+      add_new: Ajustar un novèl blocatge de domeni
       created_msg: Domeni blocat es a èsser tractat
       destroyed_msg: Lo blocatge del domeni es estat levat
       domain: Domeni
@@ -223,11 +271,13 @@ oc:
         title: Nòu blocatge domeni
       reject_media: Regetar los fichièrs mèdias
       reject_media_hint: Lèva los fichièrs gardats localament e regèta las demandas de telecargament dins lo futur. Servís pas a res per las suspensions
-      severities:
-        noop: Cap
-        silence: Silenci
-        suspend: Suspendre
-      severity: Severitat
+      reject_reports: Regetar los senhalaments
+      reject_reports_hint: Ignorar totes los senhalaments que venon d’aqueste domeni. Pas pertiment per las suspensions
+      rejecting_media: regeta los fichièrs multimèdias
+      rejecting_reports: regeta los senhalements
+      severity:
+        silence: mes en silenci
+        suspend: suspendut
       show:
         affected_accounts:
           one: Un compte de la basa de donadas tocat
@@ -237,7 +287,6 @@ oc:
           suspend: Levar la suspension de totes los comptes d’aqueste domeni
         title: Restablir lo blocatge de domeni de %{domain}
         undo: Restablir
-      title: Blòc de domeni
       undo: Restablir
     email_domain_blocks:
       add_new: Ajustar
@@ -249,19 +298,47 @@ oc:
         create: Crear un blocatge
         title: Nòu blocatge de domeni de corrièl
       title: Blocatge de domeni de corrièl
+    followers:
+      back_to_account: Tornar al compte
+      title: Seguidors de %{acct}
     instances:
-      account_count: Comptes coneguts
-      domain_name: Domeni
-      reset: Reïnicializar
-      search: Cercar
-      title: Instàncias conegudas
+      delivery_available: Liurason disponibla
+      known_accounts:
+        one: "%{count} compte conegut"
+        other: "%{count} comptes coneguts"
+      moderation:
+        all: Totas
+        limited: Limitat
+        title: Moderacion
+      title: Federacion
+      total_blocked_by_us: Avèm blocat
+      total_followed_by_them: Sègon
+      total_followed_by_us: Seguèm
+      total_reported: Senhalament a prepaus d’eles
+      total_storage: Fichièrs junts
     invites:
+      deactivate_all: O desactivar tot
       filter:
         all: Totes
         available: Disponibles
         expired: Expirats
         title: Filtre
       title: Convits
+    relays:
+      add_new: Ajustar un nòu relai
+      delete: Suprimir
+      description_html: Un <strong> relai de federacion</strong> es un servidor intermediari qu’escàmbia de bèls volumes de tuts publics entre servidors que son abonats e i publican.<strong>Pòt ajudar de pichons e mejans servidors a trobar de contenguts del fediverse estant</strong>, qu’autrament demandariá als utilizaires locals de s’abonar manualament a d’autres monde marcats sus de servidors alonhats.
+      disable: Desactivar
+      disabled: Desactivat
+      enable: Activar
+      enable_hint: Un còp activat, vòstre servidor s’abonarà a totes los tuts publics del relai estant, e començarà de mandar sos tuts publics a aqueste d’enlà.
+      enabled: Activat
+      inbox_url: URL del relai
+      pending: En espèra d’aprovacion del relai
+      save_and_enable: Salvar e activar
+      setup: Configurar una connexion relai
+      status: Estatut
+      title: Relais
     report_notes:
       created_msg: Nòta de moderacion corrèctament creada !
       destroyed_msg: Nòta de moderacion corrèctament suprimida !
@@ -276,7 +353,6 @@ oc:
       comment:
         none: Pas cap
       created_at: Creacion
-      id: ID
       mark_as_resolved: Marcar coma resolgut
       mark_as_unresolved: Marcar coma pas resolgut
       notes:
@@ -287,42 +363,46 @@ oc:
         placeholder: Explicatz las accions que son estadas menadas o quicòm de ligat al senhalament…
       reopen: Tornar dobrir lo rapòrt
       report: 'Senhalament #%{id}'
-      report_contents: Contengut
       reported_account: Compte senhalat
       reported_by: Senhalat per
       resolved: Resolgut
-      resolved_msg: Rapòrt corrèctament resolgut  !
-      silence_account: Metre lo compte en silenci
+      resolved_msg: Rapòrt corrèctament resolgut !
       status: Estatut
-      suspend_account: Suspendre lo compte
-      target: Cibla
       title: Senhalament
       unassign: Levar
-      unresolved: Pas resolguts
+      unresolved: Pas resolgut
       updated_at: Actualizat
-      view: Veire
     settings:
       activity_api_enabled:
         desc_html: Nombre d’estatuts publicats, d’utilizaires actius e de novèlas inscripcions en rapòrt setmanièr
-        title: Publica las estatisticas totalas de l’activitat dels utilizaires
+        title: Publicar las estatisticas totalas de l’activitat dels utilizaires
       bootstrap_timeline_accounts:
         desc_html: Separatz los noms d’utilizaire amb de virgula. Pas que los comptes locals e pas clavats foncionaràn. Se lo camp es void los admins seràn selecionats.
         title: Per defaut los nòuvenguts sègon
       contact_information:
         email: Picatz una adreça de corrièl
         username: Picatz un nom d’utilizaire
+      custom_css:
+        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
         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: Publica la lista de las instàncias conegudas
+        title: Publicar la lista de las instàncias conegudas
       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
+      profile_directory:
+        desc_html: Permet als utilizaires d’èsser trobats
+        title: Activar l’annuari de perfils
       registrations:
         closed_message:
-          desc_html: Afichat sus las pagina d’acuèlh quand las inscripcions son tampadas.<br>Podètz utilizar de balisas HTML
+          desc_html: Mostrat sus las pagina d’acuèlh quand las inscripcions son tampadas.<br>Podètz utilizar de balisas HTML
           title: Messatge de barradura de las inscripcions
         deletion:
           desc_html: Autorizar lo monde a suprimir lor compte
@@ -340,11 +420,14 @@ oc:
         desc_html: Mostrar lo badge Personal sus la pagina de perfil
         title: Mostrar lo badge personal
       site_description:
-        desc_html: Afichada jos la forma de paragraf sus la pagina d’acuèlh e utilizada coma balisa meta. Podètz utilizar de balisas HTML, en particular <code>&lt;a&gt;</code> e <code>&lt;em&gt;</code>.
+        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
       site_description_extended:
         desc_html: Afichada sus la pagina d’informacion complementària del site<br>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
       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
@@ -366,6 +449,7 @@ oc:
       media:
         title: Mèdia
       no_media: Cap de mèdia
+      no_status_selected: Cap d’estatut pas cambiat estant que cap èra pas seleccionat
       title: Estatuts del compte
       with_media: Amb mèdia
     subscriptions:
@@ -375,7 +459,21 @@ oc:
       last_delivery: Darrièra distribucion
       title: WebSub
       topic: Subjècte
+    tags:
+      accounts: Comptes
+      hidden: Amagat
+      hide: Amagar dins l’annuari
+      name: Etiqueta
+      title: Etiquetas
+      unhide: Aparéisser dins l’annuari
+      visible: Visible
     title: Administracion
+    warning_presets:
+      add_new: N’ajustar un nòu
+      delete: Escafar
+      edit: Modificar
+      edit_preset: Modificar lo tèxt predefinit d’avertiment
+      title: Gerir los tèxtes predefinits
   admin_mailer:
     new_report:
       body: "%{reporter} a senhalat %{target}"
@@ -465,7 +563,7 @@ oc:
     formats:
       default: "%e/%m/%Y"
       long: Lo %e %B de %Y
-      short: "%e %b. de %Y"
+      short: "%e %B de %Y"
     month_names:
     - None
     - de genièr
@@ -489,7 +587,7 @@ oc:
       about_x_hours: "%{count} h"
       about_x_months: "%{count} meses"
       about_x_years: "%{count} ans"
-      almost_x_years: "%{count}ans"
+      almost_x_years: "%{count} ans"
       half_a_minute: Ara
       less_than_x_minutes: "%{count} min"
       less_than_x_seconds: Ara meteis
@@ -509,6 +607,16 @@ oc:
     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_title: Disponibilitat del contengut difusat
+  directories:
+    directory: Annuari de perfils
+    enabled: Sètz actualament listat dins l'annuari.
+    enabled_but_waiting: Avètz causit d'èsser listat dins l'annuari mas avètz pas encara lo nombre minimum de seguidors (%{min_followers}) per i èsser listat.
+    explanation: Trobar d’utilizaires segon lor interèsses
+    explore_mastodon: Explorar %{title}
+    how_to_enable: Sètz pas actualament listat dins l’annuari. Podètz cambiar aquò çai-jos. Utilizatz d'etiquetas dins vòstre tèxt de bio per èsser listat amb d’etiquetas especificas !
+    people:
+      one: "%{count} persona"
+      other: "%{count} personas"
   errors:
     '403': Avètz pas l’autorizacion de veire aquesta pagina.
     '404': La pagina que recercatz existís pas.
@@ -520,7 +628,7 @@ oc:
     '500':
       content: Un quicomet a pas foncionat coma caliá.
       title: Aquesta pagina es pas corrècta
-    noscript_html: Per utilizar l’aplicacion web de Mastodon, mercés d’activar JavaScript. O podètz utilizar <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">una aplicacion</a> per vòstra plataforma coma alernativa.
+    noscript_html: Per utilizar l’aplicacion web de Mastodon, mercés d’activar JavaScript. O podètz utilizar <a href="%{apps_path}">una aplicacion</a> per vòstra plataforma coma alernativa.
   exports:
     archive_takeout:
       date: Data
@@ -531,7 +639,9 @@ oc:
       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
   filters:
@@ -562,9 +672,13 @@ oc:
     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:
     changes_saved_msg: Cambiaments ben realizats !
-    powered_by: propulsat per %{link}
+    copy: Copiar
     save_changes: Salvar los cambiaments
     validation_errors:
       one: I a quicòm que truca ! Mercés de corregir l’error çai-jos
@@ -595,13 +709,11 @@ oc:
       one: 1 persona
       other: "%{count} personas"
     max_uses_prompt: Cap de limit
-    prompt: Generatz e partejatz los ligams per donar accès a aquesta instància
+    prompt: Generar e partejar los ligams per donar accès a aquesta instància
     table:
       expires_at: Expirats
       uses: Usatges
     title: Convidar de mond
-  landing_strip_html: "<strong>%{name}</strong> utiliza %{link_to_root_path}. Podètz lo/la sègre o interagir amb el o ela s’avètz un compte ont que siasque sul fediverse."
-  landing_strip_signup_html: S’es pas lo cas, podètz <a href="%{sign_up_path}">vos marcar aquí</a>.
   lists:
     errors:
       limit: Avètz atengut lo maximum de listas
@@ -678,10 +790,25 @@ oc:
     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
     prompt: 'Sètz per sègre :'
+    reason_html: "<strong>Perque aquesta etapa es necessària ?</strong><code>%{instance}</code> es benlèu pas lo servidor ont vos marquèretz, doncas nos cal vos redirigir cap a vòstre prim servidor per començar."
+  remote_interaction:
+    favourite:
+      proceed: Contunhar per metre en favorit
+      prompt: 'Volètz metre en favorit aqueste tut :'
+    reblog:
+      proceed: Contunhar per repartejar
+      prompt: 'Volètz repartejar aqueste tut :'
+    reply:
+      proceed: Contunhar per respondre
+      prompt: 'Volètz respondre a aqueste tut :'
   remote_unfollow:
     error: Error
     title: Títol
     unfollowed: Pas mai seguit
+  scheduled_statuses:
+    over_daily_limit: Avètz passat la limita de %{limit}  tuts programats per aquel jorn
+    over_total_limit: Avètz passat la limita de %{limit}  tuts programats
+    too_soon: La data planificada deu èsser dins lo futur
   sessions:
     activity: Darrièra activitat
     browser: Navigator
@@ -761,6 +888,7 @@ oc:
       private: Se pòt pas penjar los tuts pas publics
       reblog: Se pòt pas penjar un tut partejat
     show_more: Ne veire mai
+    sign_in_to_participate: Inscrivètz-vos per participar a la conversacion
     title: '%{name} : "%{quote}"'
     visibilities:
       private: Seguidors solament
@@ -770,7 +898,6 @@ oc:
       unlisted: Pas listat
       unlisted_long: Tot lo monde pòt veire mai serà pas visible sul flux public
   stream_entries:
-    click_to_show: Clicatz per veire
     pinned: Tut penjat
     reblogged: a partejat
     sensitive_content: Contengut sensible
@@ -779,11 +906,12 @@ oc:
       <h2>Politica de confidencialitat</h2>
       <h3 id="collect">Quinas informacions reculhèm ?</h3>
 
-      <li>
-      <ul><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 vist 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’acion 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>
+        <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>
 
       <hr class="spacer" />
@@ -795,8 +923,68 @@ oc:
       <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>Per enviar periodicament de corrièls &mdash; 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>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" />
+
+      <h3 id="protect">Cossí protegèm vòstras informacions ?</h3>
+
+      <p>Apliquem tota una mena de mesuras de seguretat per manténer la fisança de vòstras informacions personalas quand las picatz, mandatz, o i accedètz. Entre aquelas, vòstre session de navigacion, coma lo trafic entre vòstra aplicacion e l’API, son securizats amb SSL e lo senhal es copat en tròces en emplegar un algorisme fòrt a sens unic. Podètz activar l’autentificacion en dos temps pels accèsses futurs a vòstre compte.</p>
+      <hr class="spacer" />
+
+      <h3 id="data-retention">Quala es nòstra politica de conservacion de donadas ?</h3>
+
+      <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>
+      </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>
+
+      <p>Podètz suprimir sens anullacion possibla vòstre compte quand volgatz.</p>
+
+      <hr class="spacer"/>
+
+
+      <h3 id="cookies">Utilizem de cookies ?</h3>
+
+      <p>Òc-ben. Los cookies son de pichons fichièrs qu’un site o sos provesidors de servicis plaçan dins lo disc dur de vòstre ordenador via lo navigator Web (Se los acceptatz). Aqueles cookies permeton al site de reconéisser vòstre navigator e se tenètz un compte enregistrat de l’associar a vòstre compte.</p>
+
+      <p>Empleguem de cookies per comprendre e enregistrar vòstras preferéncias per vòstras visitas venentas</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Divulguem d’informacions a de tèrces ?</h3>
+
+
+      <p>Vendèm pas, comercem o qualque transferiment que siasque a de tèrces vòstras informacions personalas identificablas. Aquò inclutz pas los tèrces partits de confisança que nos assiston a menar nòstre site, menar nòstre afar o vos servir, baste que son d’acòrd per gardar aquelas informacions confidencialas. Pòt tanben arribar que liberèssem vòstras informacions quand cresèm qu’es apropriat d’o far per se sometre a la lei, per refortir nòstras politicas, o per protegir los dreches, proprietats o seguritat de qualqu’un o de nosautres.</p>
+
+      <p>Vòstre contengut public pòt èsser telecargat per los autres servidors del malhum. Vòstras publicacions publicas e las dels seguidors solament son enviadas als servidors qu’albergan vòstres seguidors, los messatges dirèctes son mandats als servidors dels destinaris se son pas de vòstra instància.</p>
+
+      <p>Quand autorizatz una aplicacion d’utilizar vòstre compte, segon l’encastre que volètz permetre, pòt accedir a l’informacion de vòstre perfil public, vòstra lista d’abonaments, vòstres seguidors, vòstras listas, totas vòstras publicacions e vòstres favorits. Las aplicacions pòdon pas jamai accedir a vòstra adreça electronica o vòstre senhal.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Utilizacion del site pels enfants</h3>
+
+      <p>S’aqueste servidor es en EU o la EEA : òstre site, nòstres produches e servicis son totas a destinacion de monde de mai de 16 ans. S’avètz mens de 16 ans, per cumplir lo RGPD (<a href="https://ca.wikipedia.org/wiki/Reglament_General_de_Protecci%C3%B3_de_Dades">Reglament General de Proteccion de Donadas</a>) utilizetz pas aqueste site.</p>
+
+      <p>S’aqueste servidor se tròba en los Estats Units : nòstre site, nòstres produches e servicis son totas a destinacion de monde de mai de 13 ans. S’avètz mens de 13 ans, per acontentar las exigéncias del COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) utilizetz pas aqueste site.</p>
+
+      <p>Las exigéncias legalas pòdon èsser diferentas se lo servidor es en una autra juridiccion</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Cambiament dins nòstra politica de confidencialitat</h3>
+
+      <p>Se decidèm de cambiar nòstra politica de confidencialitat, publicarem los cambiaments sus aquesta pagina.</p>
+
+      <p>Aqueste document es jos licéncia CC-BY-SA. Darrièra mesa a jorn lo 4 de març de 2018</p>
+
+      <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
@@ -805,6 +993,7 @@ oc:
   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.
@@ -826,6 +1015,22 @@ oc:
       explanation: Avètz demandat una salvagarda complèta de vòstre compte Mastodon. Es prèsta per telecargament !
       subject: Vòstre archiu es prèst per telecargament
       title: Archiu per emportar
+    warning:
+      explanation:
+        disable: Quand vòstre compte es gelat, las donadas d’aqueste demòran senceras, mas podètz pas realizar cap d’accion fins que siá desblocat.
+        silence: Del temps que vòstre compte es limitat, solament lo monde que vos sègon veiràn vòstres tuts sus aqueste servidor, e poiriatz èsser tirat de mantunas listas publicas. Pasmens, d’autres vos pòdon sègre manualament.
+        suspend: Vòstre compte es suspendut e totes vòstres tuts e fichièrs enviats son estats suprimits sens retorn possible d’aqueste servidor e los de vòstres seguidors.
+      review_server_policies: Repassar las politicas del servidor
+      subject:
+        disable: Vòstre compte %{acct} es gelat
+        none: Avertiment per %{acct}
+        silence: Vòstre compte %{acct} es limitat
+        suspend: Vòstre compte %{acct} es suspendut
+      title:
+        disable: Compte gelat
+        none: Avertiment
+        silence: Compte limitat
+        suspend: Compte suspendut
     welcome:
       edit_profile_action: Configuracion del perfil
       edit_profile_step: Podètz personalizar lo perfil en mandar un avatard, cambiar l’escais-nom e mai. Se volètz repassar las demandas d’abonaments abans que los nòus seguidors pòscan veire vòstre perfil, podètz clavar vòstre compte.
@@ -837,7 +1042,6 @@ oc:
       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
-      tip_bridge_html: Se venètz de Twitter, podètz trobar vòstres amics sus Mastodon en utilizant l‘<a href="%{bridge_url}">aplicacion de Pont</a>. Aquò fonciona pas que s’utilizan lo Pont tanben !
       tip_federated_timeline: Lo flux d’actualitat federat es una vista generala del malhum Mastodon. Mas aquò inclutz solament lo monde que vòstres vesins sègon, doncas es pas complèt.
       tip_following: Seguètz l’administrator del servidor per defaut. Per trobar de monde mai interessant, agachatz lo flux d’actualitat local e lo global.
       tip_local_timeline: Lo flux d’actualitat local es una vista del monde de %{instance}. Son vòstres vesins dirèctes !
@@ -845,8 +1049,12 @@ oc:
       tips: Astúcias
       title: Vos desirem la benvenguda a bòrd %{name} !
   users:
+    follow_limit_reached: Podètz pas sègre mai de %{limit} personas
     invalid_email: L’adreça de corrièl es invalida
     invalid_otp_token: Còdi d’autentificacion en dos temps invalid
     otp_lost_help_html: Se perdatz l’accès al dos, podètz benlèu contactar %{email}
     seamless_external_login: Sètz connectat via un servici extèrn, los paramètres de senhal e de corrièl son doncas pas disponibles.
     signed_in_as: 'Session a :'
+  verification:
+    explanation_html: 'Podètz <strong>verificar vosautres meteisses coma proprietari dels ligams per las metadonadas de vòstre perfil</strong>. Per aquò far, lo site Web ligat deu conténer un ligam cap a vòstre perfil Mastodon. Lo ligam <strong>deu</strong> aver un atribut <code>rel="me"</code>. Lo contengut tèxte del ligam impòrta pas. Vaquí un exemple :'
+    verification: Verificacion
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index a6e5241fc76fa062d30a6cc76020373541571ae0..5ce007ba9f88961de88f4f571f055393f532f40e 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -5,13 +5,13 @@ pl:
     about_mastodon_html: Mastodon jest wolną i otwartą siecią społecznościową, zdecentralizowaną alternatywą dla zamkniętych, komercyjnych platform.
     about_this: O tej instancji
     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.
     contact: Kontakt
     contact_missing: Nie ustawiono
     contact_unavailable: Nie dotyczy
-    description_headline: Czym jest %{domain}?
-    domain_count_after: instancjami
-    domain_count_before: Serwer połączony z
+    documentation: Dokumentacja
     extended_description_html: |
       <h3>Dobre miejsce na zasady użytkowania</h3>
       <p>Nie ustawiono jeszcze szczegółowego opisu</p>
@@ -28,25 +28,49 @@ pl:
     hosted_on: Mastodon uruchomiony na %{domain}
     learn_more: Dowiedz się więcej
     other_instances: Lista instancji
+    privacy_policy: Polityka prywatności
     source_code: Kod źródłowy
-    status_count_after: wpisów
+    status_count_after:
+      few: wpisów
+      many: wpisów
+      one: wpisu
+      other: wpisów
     status_count_before: SÄ… autorami
-    user_count_after: użytkowników
+    terms: Zasady użytkowania
+    user_count_after:
+      few: użytkowników
+      many: użytkowników
+      one: użytkownik
+      other: użytkowników
     user_count_before: Z serwera korzysta
     what_is_mastodon: Czym jest Mastodon?
   accounts:
+    choices_html: 'Polecani przez %{name}:'
     follow: Śledź
-    followers: ÅšledzÄ…cy
-    following: Åšledzeni
+    followers:
+      few: śledzących
+      many: śledzących
+      one: śledzący
+      other: ÅšledzÄ…cych
+    following: Åšledzonych
+    joined: Dołączył(a) %{date}
+    last_active: ostatnio aktywny(-a)
+    link_verified_on: Własność tego odnośnika została sprawdzona %{date}
     media: Zawartość multimedialna
     moved_html: "%{name} korzysta teraz z konta %{new_profile_link}:"
     network_hidden: Ta informacja nie jest dostępna
     nothing_here: Niczego tu nie ma!
     people_followed_by: Konta śledzone przez %{name}
     people_who_follow: Osoby, które śledzą konto %{name}
-    posts: Wpisy
+    pin_errors:
+      following: Musisz śledzić osobę, którą chcesz polecać
+    posts:
+      few: wpisy
+      many: wpisów
+      one: wpis
+      other: Wpisów
+    posts_tab_heading: Wpisy
     posts_with_replies: Wpisy z odpowiedziami
-    remote_follow: Śledź zdalnie
     reserved_username: Ta nazwa użytkownika jest zarezerwowana
     roles:
       admin: Administrator
@@ -54,6 +78,9 @@ pl:
       moderator: Moderator
     unfollow: Przestań śledzić
   admin:
+    account_actions:
+      action: Wykonaj działanie
+      title: Wykonaj działanie moderacyjne na %{acct}
     account_moderation_notes:
       create: Pozostaw notatkÄ™
       created_msg: Pomyślnie dodano notatkę moderacyjną!
@@ -73,6 +100,7 @@ pl:
       confirm: Potwierdź
       confirmed: Potwierdzono
       confirming: Potwierdzanie
+      deleted: Usunięto
       demote: Degraduj
       disable: Dezaktywuj
       disable_two_factor_authentication: Wyłącz uwierzytelnianie dwuetapowe
@@ -88,8 +116,11 @@ pl:
       followers: ÅšledzÄ…cy
       followers_url: Adres śledzących
       follows: Åšledzeni
+      header: Nagłówek
       inbox_url: Adres skrzynki
+      invited_by: Zaproszony(-a) przez
       ip: Adres IP
+      joined: Dołączył(-a)
       location:
         all: Wszystkie
         local: Lokalne
@@ -99,6 +130,7 @@ pl:
       media_attachments: Załączniki multimedialne
       memorialize: Przełącz na „In Memoriam”
       moderation:
+        active: Aktywne
         all: Wszystkie
         silenced: Wyciszone
         suspended: Zawieszone
@@ -106,20 +138,18 @@ pl:
       moderation_notes: Notatki moderacyjne
       most_recent_activity: Najnowsza aktywność
       most_recent_ip: Ostatnie IP
+      no_limits_imposed: Nie nałożono ograniczeń
       not_subscribed: Nie zasubskrybowano
-      order:
-        alphabetic: Alfabetycznie
-        most_recent: Najnowsze
-        title: Kolejność
       outbox_url: Adres skrzynki nadawczej
-      perform_full_suspension: Całkowicie zawieś
+      perform_full_suspension: ZawieÅ›
       profile_url: Adres profilu
       promote: PodnieÅ› uprawnienia
       protocol: Protokół
       public: Publiczne
       push_subscription_expires: Subskrypcja PuSH wygasa
-      redownload: Odśwież awatar
+      redownload: Odśwież profil
       remove_avatar: Usun awatar
+      remove_header: Usuń nagłówek
       resend_confirmation:
         already_confirmed: To konto zostało już potwierdzone
         send: Wyślij ponownie e-mail z potwierdzeniem
@@ -138,48 +168,53 @@ pl:
       shared_inbox_url: Adres udostępnianej skrzynki
       show:
         created_reports: Zgłoszenia tego użytkownika
-        report: zgłoszeń
         targeted_reports: Zgłoszenia dotyczące tego użytkownika
       silence: Wycisz
+      silenced: Wyciszono
       statuses: Wpisy
       subscribe: Subskrybuj
+      suspended: Zawieszono
       title: Konta
       unconfirmed_email: Niepotwierdzony adres e-mail
       undo_silenced: Cofnij wyciszenie
       undo_suspension: Cofnij zawieszenie
       unsubscribe: Przestań subskrybować
       username: Nazwa użytkownika
+      warn: Ostrzeż
       web: Sieć
     action_logs:
       actions:
-        assigned_to_self_report: "%{name} przypisał sobie zgłoszenie %{target}"
-        change_email_user: "%{name} zmienił adres-email użytkownika %{target}"
-        confirm_user: "%{name} potwierdził adres e-mail użytkownika %{target}"
-        create_custom_emoji: "%{name} dodał nowe emoji %{target}"
-        create_domain_block: "%{name} zablokował domenę %{target}"
-        create_email_domain_block: "%{name} dodał domenę e-mail %{target} na czarną listę"
-        demote_user: "%{name} zdegradował użytkownika %{target}"
-        destroy_domain_block: "%{name} odblokował domenę %{target}"
-        destroy_email_domain_block: "%{name} usunÄ…Å‚ domenÄ™ e-mail %{target} z czarnej listy"
-        destroy_status: "%{name} usunął wpis użytkownika %{target}"
-        disable_2fa_user: "%{name} wyłączył uwierzytelnianie dwustopniowe użytkownikowi %{target}"
-        disable_custom_emoji: "%{name} wyłączył emoji %{target}"
-        disable_user: "%{name} zablokował możliwość logowania użytkownikowi %{target}"
-        enable_custom_emoji: "%{name} włączył emoji %{target}"
-        enable_user: "%{name} przywrócił możliwość logowania użytkownikowi %{target}"
-        memorialize_account: "%{name} nadał kontu %{target} status in memoriam"
-        promote_user: "%{name} podniósł uprawnienia użytkownikowi %{target}"
-        remove_avatar_user: "%{name} usunął awatar użytkownikowi %{target}"
-        reopen_report: "%{name} otworzył ponownie zgłoszenie %{target}"
-        reset_password_user: "%{name} przywrócił hasło użytkownikowi %{target}"
-        resolve_report: "%{name} rozwiązał zgłoszenie %{target}"
-        silence_account: "%{name} wyciszył konto %{target}"
-        suspend_account: "%{name} zawiesił konto %{target}"
-        unassigned_report: "%{name} cofnął przypisanie zgłoszenia %{target}"
-        unsilence_account: "%{name} cofnÄ…Å‚ wyciszenie konta %{target}"
-        unsuspend_account: "%{name} cofnÄ…Å‚ zawieszenie konta %{target}"
-        update_custom_emoji: "%{name} zaktualizował emoji %{target}"
-        update_status: "%{name} zaktualizował wpis użytkownika %{target}"
+        assigned_to_self_report: "%{name} przypisał(a) sobie zgłoszenie %{target}"
+        change_email_user: "%{name} zmienił(a) adres e-mail użytkownika %{target}"
+        confirm_user: "%{name} potwierdził(a) adres e-mail użytkownika %{target}"
+        create_account_warning: "%{name} wysłał(a) ostrzeżenie do %{target}"
+        create_custom_emoji: "%{name} dodał(a) nowe emoji %{target}"
+        create_domain_block: "%{name} zablokował(a) domenę %{target}"
+        create_email_domain_block: "%{name} dodał(a) domenę e-mail %{target} na czarną listę"
+        demote_user: "%{name} zdegradował(a) użytkownika %{target}"
+        destroy_custom_emoji: "%{name} usunął(-ęła) emoji %{target}"
+        destroy_domain_block: "%{name} odblokował(a) domenę %{target}"
+        destroy_email_domain_block: "%{name} usunął(-ęła) domenę e-mail %{target} z czarnej listy"
+        destroy_status: "%{name} usunął(-ęła) wpis użytkownika %{target}"
+        disable_2fa_user: "%{name} wyłączył(a) uwierzytelnianie dwustopniowe użytkownikowi %{target}"
+        disable_custom_emoji: "%{name} wyłączył(a) emoji %{target}"
+        disable_user: "%{name} zablokował(a) możliwość logowania użytkownikowi %{target}"
+        enable_custom_emoji: "%{name} włączył(a) emoji %{target}"
+        enable_user: "%{name} przywrócił(a) możliwość logowania użytkownikowi %{target}"
+        memorialize_account: "%{name} nadał(a) kontu %{target} status in memoriam"
+        promote_user: "%{name} podniósł(a) uprawnienia użytkownikowi %{target}"
+        remove_avatar_user: "%{name} usunął(-ęła) awatar użytkownikowi %{target}"
+        reopen_report: "%{name} otworzył(a) ponownie zgłoszenie %{target}"
+        reset_password_user: "%{name} przywrócił(a) hasło użytkownikowi %{target}"
+        resolve_report: "%{name} rozwiązał(a) zgłoszenie %{target}"
+        silence_account: "%{name} wyciszył(a) konto %{target}"
+        suspend_account: "%{name} zawiesił(a) konto %{target}"
+        unassigned_report: "%{name} cofnął(-ęła) przypisanie zgłoszenia %{target}"
+        unsilence_account: "%{name} cofnął(-ęła) wyciszenie konta %{target}"
+        unsuspend_account: "%{name} cofnął(-ęła) zawieszenie konta %{target}"
+        update_custom_emoji: "%{name} zaktualizował(a) emoji %{target}"
+        update_status: "%{name} zaktualizował(a) wpis użytkownika %{target}"
+      deleted_status: "(usunięty wpis)"
       title: Dziennik działań administracyjnych
     custom_emojis:
       by_domain: Domeny
@@ -206,6 +241,28 @@ pl:
       update_failed_msg: Nie udało się zaktualizować emoji
       updated_msg: Pomyślnie zaktualizowano emoji!
       upload: Dodaj
+    dashboard:
+      backlog: zaległe zadania
+      config: Konfiguracja
+      feature_deletions: Usuwanie kont
+      feature_invites: Zaproszenia
+      feature_profile_directory: Katalog profilów
+      feature_registrations: Rejestracja
+      feature_relay: Przekazywanie federacji
+      features: Możliwości
+      hidden_service: Federowanie z ukrytymi usługami
+      open_reports: otwarte zgłoszenia
+      recent_users: Ostatni użytkownicy
+      search: Wyszukiwanie pełnego tekstu
+      single_user_mode: Tryb jednego użytkownika
+      software: Oprogramowanie
+      space: Używana powierzchnia
+      title: Panel administracyjny
+      total_users: łącznie użytkowników
+      trends: Na czasie
+      week_interactions: interakcje w tym tygodniu
+      week_users_active: aktywni w tym tygodniu
+      week_users_new: rejestracje w tym tygodniu
     domain_blocks:
       add_new: Dodaj nowÄ…
       created_msg: Blokada domen jest przetwarzana
@@ -222,22 +279,24 @@ pl:
         title: Nowa blokada domen
       reject_media: Odrzucaj pliki multimedialne
       reject_media_hint: Usuwa przechowywane lokalnie pliki multimedialne i nie pozwala na ich pobieranie. Nieprzydatne przy zawieszeniu
-      severities:
-        noop: Nic nie rób
-        silence: Wycisz
-        suspend: ZawieÅ›
-      severity: Priorytet
+      reject_reports: Odrzucaj zgłoszenia
+      reject_reports_hint: Zgłoszenia z tej instancji będą ignorowane. Nieprzydatne przy zawieszeniu
+      rejecting_media: pliki multimedialne sÄ… odrzucane
+      rejecting_reports: zgłoszenia są odrzucane
+      severity:
+        silence: wyciszono
+        suspend: zawieszono
       show:
         affected_accounts:
-          many: Dotyczy %{count} kont w bazie danych
-          one: Dotyczy jednego konta w bazie danych
-          other: Dotyczy %{count} kont w bazie danych
+          few: Dotknęło %{count} kont w bazie danych
+          many: Dotknęło %{count} kont w bazie danych
+          one: Dotknęło jedno konto w bazie danych
+          other: Dotknęło %{count} kont w bazie danych
         retroactive:
           silence: Odwołaj wyciszenie wszystkich kont w tej domenie
           suspend: Odwołaj zawieszenie wszystkich kont w tej domenie
         title: Odwołaj blokadę dla domeny %{domain}
         undo: Cofnij
-      title: Zablokowane domeny
       undo: Cofnij
     email_domain_blocks:
       add_new: Dodaj nowÄ…
@@ -249,19 +308,49 @@ pl:
         create: Utwórz blokadę
         title: Nowa blokada domeny e-mail
       title: Blokowanie domen e-mail
+    followers:
+      back_to_account: Wróć do konta
+      title: ÅšledzÄ…cy %{acct}
     instances:
-      account_count: Znane konta
-      domain_name: Domena
-      reset: Przywróć
-      search: Szukaj
+      delivery_available: Doręczanie jest dostępne
+      known_accounts:
+        few: "%{count} znane konta"
+        many: "%{count} znane konta"
+        one: "%{count} znane konto"
+        other: "%{count} znane konta"
+      moderation:
+        all: Wszystkie
+        limited: Ograniczone
+        title: Moderacja
       title: Znane instancje
+      total_blocked_by_us: Zablokowane przez nas
+      total_followed_by_them: Åšledzeni przez nich
+      total_followed_by_us: Åšledzeni przez nas
+      total_reported: Zgłoszenia dotyczące ich
+      total_storage: Załączniki multimedialne
     invites:
+      deactivate_all: Unieważnij wszystkie
       filter:
         all: Wszystkie
         available: Dostępne
         expired: Wygasłe
         title: Filtruj
       title: Zaproszenia
+    relays:
+      add_new: Dodaj nowy
+      delete: Usuń
+      description_html: "<strong>Przekaźnik federacji</strong> jest pośredniczącym serwerem wymieniającym duże ilości publicznych wpisów pomiędzy serwerami które subskrybują je i publikują na nich. <strong>Pomaga to małym i średnim instancją poznawać nową zawartość z Fediwersum</strong>, co w innym przypadku wymagałoby od użytkowników ręcznego śledzenia osób z innych serwerów."
+      disable: Wyłącz
+      disabled: Wyłączony
+      enable: Włącz
+      enable_hint: Jeżeli włączone, Twój serwer zasubskrybuje wszystkie publiczne wpisy z tego przekaźnika i zacznie wysyłać tam publiczne wpisy z tego serwera.
+      enabled: Włączony
+      inbox_url: Adres przekaźnika
+      pending: Oczekiwanie na przyjęcie przez przekaźnik
+      save_and_enable: Zapisz i aktywuj
+      setup: Skonfiguruj połączenie z przekaźnikiem
+      status: Stan
+      title: Przekaźniki
     report_notes:
       created_msg: Pomyslnie utworzono notatkÄ™ moderacyjnÄ….
       destroyed_msg: Pomyślnie usunięto notatkę moderacyjną.
@@ -276,7 +365,6 @@ pl:
       comment:
         none: Brak
       created_at: Zgłoszono
-      id: ID
       mark_as_resolved: Oznacz jako rozwiÄ…zane
       mark_as_unresolved: Oznacz jako nierozwiÄ…zane
       notes:
@@ -287,20 +375,15 @@ pl:
         placeholder: Opisz wykonane akcje i inne szczegóły dotyczące tego zgłoszenia…
       reopen: Otwórz ponownie
       report: 'Zgłoszenie #%{id}'
-      report_contents: Zawartość
       reported_account: Zgłoszone konto
       reported_by: Zgłaszający
       resolved: RozwiÄ…zane
       resolved_msg: Pomyślnie rozwiązano zgłoszenie.
-      silence_account: Wycisz konto
       status: Stan
-      suspend_account: ZawieÅ› konto
-      target: Cel
       title: Zgłoszenia
       unassign: Cofnij przypisanie
       unresolved: NierozwiÄ…zane
       updated_at: Zaktualizowano
-      view: Wyświetl
     settings:
       activity_api_enabled:
         desc_html: Liczy publikowane lokalnie wpisy, aktywnych użytkowników i nowe rejestracje w ciągu danego tygodnia
@@ -311,15 +394,24 @@ pl:
       contact_information:
         email: Służbowy adres e-mail
         username: Nazwa użytkownika do kontaktu
+      custom_css:
+        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 instancji
         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
       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
+      profile_directory:
+        desc_html: Pozwalaj na poznawanie użytkowników
+        title: Włącz katalog profilów
       registrations:
         closed_message:
           desc_html: Wyświetlana na stronie głównej, gdy możliwość otwarej rejestracji nie jest dostępna. Możesz korzystać z tagów HTML
@@ -340,13 +432,16 @@ pl:
         desc_html: Pokazuj odznakę uprawnień na stronie profilu użytkownika
         title: Pokazuj odznakÄ™ administracji
       site_description:
-        desc_html: Akapit wprowadzający, widoczny na stronie głównej i znacznikach meta. Możesz korzystać z tagów HTML, w szczególności <code>&lt;a&gt;</code> i <code>&lt;em&gt;</code>.
+        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
       site_description_extended:
-        desc_html: Dobre miejsce na zasady użytkowania, wprowadzenie i inne rzeczy, które wyróżniają tę instancję. Możesz korzystać z tagów HTML
+        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
         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
       site_terms:
-        desc_html: Miejsce na własną politykę prywatności, zasady użytkowania i inne unormowania prawne. Możesz korzystać z tagów HTML
+        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
       thumbnail:
@@ -366,6 +461,7 @@ pl:
       media:
         title: Media
       no_media: Bez zawartości multimedialnej
+      no_status_selected: Żaden wpis nie został zmieniony, bo żaden nie został wybrany
       title: Wpisy konta
       with_media: Z zawartością multimedialną
     subscriptions:
@@ -375,11 +471,25 @@ pl:
       last_delivery: Ostatnio doręczono
       title: WebSub
       topic: Temat
+    tags:
+      accounts: Konta
+      hidden: Ukryte
+      hide: Ukryj w katalogu
+      name: Hashtag
+      title: Hashtagi
+      unhide: Pokazuj w katalogu
+      visible: Widoczne
     title: Administracja
+    warning_presets:
+      add_new: Dodaj nowy
+      delete: Usuń
+      edit: Edytuj
+      edit_preset: Edytuj szablon ostrzeżenia
+      title: Zarządzaj szablonami ostrzeżeń
   admin_mailer:
     new_report:
-      body: Użytkownik %{reporter} zgłosił %{target}
-      body_remote: Użytkownik instancji %{domain} zgłosił %{target}
+      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})
   application_mailer:
     notification_preferences: Zmień ustawienia e-maili
@@ -397,18 +507,18 @@ 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ś się z <a href="%{rules_path}">informacjami o instancji</a> i <a href="%{terms_path}">zasadami korzystania z usługi</a>.
+    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>.
     change_password: Hasło
     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.
-    didnt_get_confirmation: Nie otrzymałeś instrukcji weryfikacji?
+    didnt_get_confirmation: Nie otrzymałeś(-aś) instrukcji weryfikacji?
     forgot_password: Nie pamiętasz hasła?
     invalid_reset_password_token: Token do resetowania hasła jest nieprawidłowy lub utracił ważność. Spróbuj uzyskać nowy.
     login: Zaloguj siÄ™
     logout: Wyloguj siÄ™
     migrate_account: PrzenieÅ› konto
-    migrate_account_html: Jeżeli chcesz skonfigurować przekierowanie z obecnego konta na inne, możesz <a href="%{path}">skonfigurować to tutaj</a>.
+    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:
@@ -453,6 +563,15 @@ pl:
     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_title: Dostępność usuniętej zawartości
+  directories:
+    directory: Katalog profilów
+    explanation: Poznaj profile na podstawie zainteresowań
+    explore_mastodon: Odkrywaj %{title}
+    people:
+      few: "%{count} osoby"
+      many: "%{count} osób"
+      one: "%{count} osoba"
+      other: "%{count} osób"
   errors:
     '403': Nie masz uprawnień, aby wyświetlić tę stronę.
     '404': Strona, którą próbujesz odwiedzić, nie istnieje.
@@ -464,7 +583,7 @@ pl:
     '500':
       content: Przepraszamy, coś poszło nie tak, po naszej stronie.
       title: Ta strona jest nieprawidłowa
-    noscript_html: Aby korzystać z aplikacji Mastodon, włącz JavaScript. Możesz też skorzystać z jednej z <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">natywnych aplikacji</a> obsługującej Twoje urządzenie.
+    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.
   exports:
     archive_takeout:
       date: Data
@@ -475,7 +594,9 @@ pl:
       size: Rozmiar
     blocks: Zablokowani
     csv: CSV
+    domain_blocks: Blokady domen
     follows: Åšledzeni
+    lists: Listy
     mutes: Wyciszeni
     storage: UrzÄ…dzenie przechowujÄ…ce dane
   filters:
@@ -500,15 +621,16 @@ pl:
     followers_count: Liczba śledzących
     lock_link: Zablokuj swoje konto
     purge: Przestań śledzić
-    success:
-      one: W trakcie usuwania śledzących z jednej domeny…
-      other: W trakcie usuwania śledzących z %{count} domen…
+    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:
     changes_saved_msg: Ustawienia zapisane!
-    powered_by: uruchomione na %{link}
     save_changes: Zapisz zmiany
     validation_errors:
       few: Coś jest wciąż nie tak! Przejrzyj %{count} poniższe błędy
@@ -536,7 +658,7 @@ pl:
       '86400': dobie
     expires_in_prompt: Nigdy
     generate: Wygeneruj
-    invited_by: 'Zostałeś zaproszony przez:'
+    invited_by: 'Zostałeś(-aś) zaproszony(-a) przez:'
     max_uses:
       few: "%{count} użycia"
       many: "%{count} użyć"
@@ -548,8 +670,6 @@ pl:
       expires_at: Wygaśnie po
       uses: Użycia
     title: Zaproś użytkowników
-  landing_strip_html: "<strong>%{name}</strong> ma konto na %{link_to_root_path}. Możesz je śledzić i wejść z nim w interakcję jeśli masz konto gdziekolwiek w Fediwersum."
-  landing_strip_signup_html: Jeśli jeszcze go nie masz, możesz <a href="%{sign_up_path}">stworzyć konto</a>.
   lists:
     errors:
       limit: Przekroczyłeś maksymalną liczbę utworzonych list
@@ -590,13 +710,13 @@ pl:
       title: Nowy śledzący
     follow_request:
       action: Zarządzaj prośbami o możliwość śledzenia
-      body: "%{name} poprosił o możliwość śledzenia Cię"
+      body: "%{name} poprosił(a) o możliwość śledzenia Cię"
       subject: 'Prośba o możliwość śledzenia: %{name}'
       title: Nowa prośba o możliwość śledzenia
     mention:
       action: Odpowiedz
-      body: "%{name} wspomniał o Tobie w:"
-      subject: "%{name} wspomniał o Tobie"
+      body: "%{name} wspomniał(a) o Tobie w:"
+      subject: "%{name} wspomniał(a) o Tobie"
       title: Nowe wspomnienie o Tobie
     reblog:
       body: 'Twój wpis został podbity przez %{name}:'
@@ -625,7 +745,7 @@ pl:
     publishing: Publikowanie
     web: Sieć
   remote_follow:
-    acct: Podaj swój adres (nazwa@domena), z którego chcesz śledzić
+    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ź
@@ -705,9 +825,7 @@ pl:
         other: "%{count} filmów"
     boosted_from_html: Podbito przez %{acct_link}
     content_warning: 'Ostrzeżenie o zawartości: %{warning}'
-    disallowed_hashtags:
-      one: 'zawiera niedozwolony hashtag: %{tags}'
-      other: 'zawiera niedozwolone hashtagi: %{tags}'
+    disallowed_hashtags: '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
@@ -717,6 +835,7 @@ pl:
       private: Nie możesz przypiąć niepublicznego wpisu
       reblog: Nie możesz przypiąć podbicia wpisu
     show_more: Pokaż więcej
+    sign_in_to_participate: Zaloguj się, aby udzielić się w tej konwersacji
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Tylko dla śledzących
@@ -726,7 +845,6 @@ pl:
       unlisted: Niewypisane
       unlisted_long: Widoczne dla wszystkich, ale nie wyświetlane na publicznych osiach czasu
   stream_entries:
-    click_to_show: Naciśnij aby wyświetlić
     pinned: Przypięty wpis
     reblogged: podbił
     sensitive_content: Wrażliwa zawartość
@@ -736,9 +854,9 @@ 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 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>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 wspimnianych. 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>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>
 
@@ -779,15 +897,15 @@ pl:
 
       <h3 id="cookies">Czy używany plików cookies?</h3>
 
-      <p>Tak. Pliki cookies są małymi plikami, które strona lub dostawca jej usługi dostarcza na dysk twardy komputera z użyciem przeglądarki internetowej (jeżeli na to pozwoli). Pliki cookies pozwalają na rozpoznanie przeglądarki i – jeśli jesteś zarejestrowany – przypisanie jej do konta.</p>
+      <p>Tak. Pliki cookies są małymi plikami, które strona lub dostawca jej usługi dostarcza na dysk twardy komputera z użyciem przeglądarki internetowej (jeżeli na to pozwoli). Pliki cookies pozwalają na rozpoznanie przeglądarki i – jeśli jesteś zarejestrowany(-a) – przypisanie jej do konta.</p>
 
-      <p>Wykorzystujemy pliki cookies, aby przechowywać preferencję użytkowników na przyszłe wizyty.</p>
+      <p>Wykorzystujemy pliki cookies, aby przechowywać preferencje użytkowników na przyszłe wizyty.</p>
 
       <hr class="spacer" />
 
       <h3 id="disclose">Czy przekazujemy informacje osobom trzecim?</h3>
 
-      <p>Nie sprzedajemy, nie wymieniamy i nie przekazujemy osobom trzecim informacji pozwalających na identyfikację Ciebie. Nie dotyczy to zaufanym dostawcom pomagającym w prowadzeniu lub obsługiwaniu użytkowników, jeżeli zgadzają się, aby nie przekazywać dalej tych informacji. Możemy również udostępnić informacje, jeżeli uważany to za wymagane przez prawo, konieczne do wypełnienia polityki strony, przestrzegania naszych lub cudzych praw, własności i bezpieczeństwa.</p>
+      <p>Nie sprzedajemy, nie wymieniamy i nie przekazujemy osobom trzecim informacji pozwalających na identyfikację Ciebie. Nie dotyczy to zaufanych dostawców pomagających w prowadzeniu strony lub obsługiwaniu użytkowników, jeżeli zgadzają się, aby nie przekazywać dalej tych informacji. Możemy również udostępnić informacje, jeżeli uważany to za wymagane przez prawo, konieczne do wypełnienia polityki strony, przestrzegania naszych lub cudzych praw, własności i bezpieczeństwa.</p>
 
       <p>Twoja publiczna zawartość może zostać pobrana przez inne serwery w sieci. Wpisy publiczne i tylko dla śledzących są dostarczane na serwery, na których znajdują się śledzący Cię, a wiadomości bezpośrednie trafiają na serwery adresatów, jeżeli są oni użytkownikami innego serwera.</p>
 
@@ -797,9 +915,9 @@ pl:
 
       <h3 id="children">Korzystanie ze strony przez dzieci</h3>
 
-      <p>Jeżeli serwer znajduje się w UE lub w EOG: Ta strona, produkty i usługi są przeznaczone dla osób, które ukończyły 16 lat. Jeżeli nie ukończyłeś 16 roku życia, zgodnie z wymogami COPPA (<a href="https://pl.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Prawo o Ochronie Prywatności Dzieci w Internecie</a>), nie używaj tej strony.</p>
+      <p>Jeżeli serwer znajduje się w UE lub w EOG: Ta strona, produkty i usługi są przeznaczone dla osób, które ukończyły 16 lat. Jeżeli nie ukończyłeś(-aś) 16 roku życia, zgodnie z wymogami COPPA (<a href="https://pl.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Prawo o Ochronie Prywatności Dzieci w Internecie</a>), nie używaj tej strony.</p>
 
-      <p>Jeżeli serwer znajduje się w USA: Ta strona, produkty i usługi są przeznaczone dla osób, które ukończyły 13 lat. Jeżeli nie ukończyłeś 13 roku życia, zgodnie z wymogami RODO (<a href="https://pl.wikipedia.org/wiki/Ogólne_rozporządzenie_o_ochronie_danych">Ogólne rozporządzenie o ochronie danych</a>), nie używaj tej strony.</p>
+      <p>Jeżeli serwer znajduje się w USA: Ta strona, produkty i usługi są przeznaczone dla osób, które ukończyły 13 lat. Jeżeli nie ukończyłeś(-aś) 13 roku życia, zgodnie z wymogami RODO (<a href="https://pl.wikipedia.org/wiki/Ogólne_rozporządzenie_o_ochronie_danych">Ogólne rozporządzenie o ochronie danych</a>), nie używaj tej strony.</p>
 
       <p>Wymogi mogą być inne, jeżeli serwer znajduje się w innym kraju.</p>
 
@@ -820,6 +938,7 @@ pl:
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Aby kontynuować, wprowadź kod wyświetlany przez aplikację uwierzytelniającą
     description_html: Jeśli włączysz <strong>uwierzytelnianie dwuetapowe</strong>, logowanie się będzie wymagało podania tokenu wyświetlonego na Twoim telefonie.
@@ -838,9 +957,25 @@ pl:
     wrong_code: Wprowadzony kod jest niepoprawny! Czy czas serwera i urzÄ…dzenia jest poprawny?
   user_mailer:
     backup_ready:
-      explanation: Zażądałeś pełnej kopii zapasowej konta na Mastodonie. Jest ono dostępne do pobrania
+      explanation: Zażądałeś pełnej kopii zapasowej konta na Mastodonie. Jest ona dostępna do pobrania!
       subject: Twoje archiwum jest gotowe do pobrania
       title: Odbiór archiwum
+    warning:
+      explanation:
+        disable: Kiedy Twoje konto jest wyłączone, Twoje dane pozostają na serwerze, ale nie możesz wykonywać żadnych działań, zanim zostanie odblokowane.
+        silence: Kiedy Twoje konto jest ograniczone, tylko osoby które je śledzą będą widzieć Twoje wpisy. Może ono też przestać być widoczne na publicznych listach. Inni wciąż mogą zacząć Cię śledzić.
+        suspend: Twoje konto zostało zawieszone i wszystkie Twoje wpisy wraz z zawartością multimedialną zostały nieodwracalnie usunięte z tego serwera i serwerów, których użytkownicy śledzili Cię.
+      review_server_policies: Przejrzyj zasady serwera
+      subject:
+        disable: Twoje konto %{acct} zostało wyłączone
+        none: Ostrzeżenie dla %{acct}
+        silence: Twoje konto %{acct} zostało ograniczone
+        suspend: Twoje konto %{acct} zostało zawieszone
+      title:
+        disable: Konto wyłączone
+        none: Ostrzeżenie
+        silence: Konto ograniczone
+        suspend: Konto zawieszone
     welcome:
       edit_profile_action: Skonfiguruj profil
       edit_profile_step: Możesz dostować profil wysyłając awatar, obraz nagłówka, zmieniając wyświetlaną nazwę i wiele więcej. Jeżeli chcesz, możesz zablokować konto, aby kontrolować, kto może Cię śledzić.
@@ -850,9 +985,8 @@ pl:
       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.
       review_preferences_action: Zmień ustawienia
-      review_preferences_step: Upewnij się, że zmieniłeś 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.
+      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
-      tip_bridge_html: Jeżeli przybywasz z Twittera, możesz znaleźć znajomych na Mastodonie używając <a href="%{bridge_url}">aplikacji mostku</a>. Działa to tylko, jeżeli oni również z niej korzystali!
       tip_federated_timeline: Oś czasu federacji przedstawia całą sieć Mastodona. Wyświetla tylko wpisy osób, które śledzą użytkownicy Twojej instancji, więc nie jest kompletna.
       tip_following: Domyślnie śledzisz administratora/ów swojej instancji. Aby znaleźć więcej ciekawych ludzi, zajrzyj na lokalną i federalną oś czasu.
       tip_local_timeline: Lokalna oś czasu przedstawia osoby z %{instance}. To Twoi najbliżsi sąsiedzi!
@@ -860,8 +994,12 @@ pl:
       tips: Wskazówki
       title: Witaj na pokładzie, %{name}!
   users:
+    follow_limit_reached: Nie możesz śledzić więcej niż %{limit} osób
     invalid_email: Adres e-mail jest niepoprawny
     invalid_otp_token: Kod uwierzytelniajÄ…cy jest niepoprawny
     otp_lost_help_html: Jeżeli utracisz dostęp do obu, możesz skontaktować się z %{email}
     seamless_external_login: Zalogowano z użyciem zewnętrznej usługi, więc ustawienia hasła i adresu e-mail nie są dostępne.
     signed_in_as: 'Zalogowany jako:'
+  verification:
+    explanation_html: 'Możesz <strong>zweryfikować siebie jako właściciela stron, do których odnośniki znajdują się w metadanych</strong>. Aby to zrobić, strona musi zawierać odnośnik do Twojego profilu na Mastodonie. Odnośnik <strong>musi</strong> zawierać atrybut <code>rel="me"</code>. Jego zawartość nie ma znaczenia. Przykład:'
+    verification: Weryfikacja
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index d64150a954c414e18cebd32477f61c6f213cc46a..785860ed4911205390b3793b9c71f85e9cf71f1b 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -5,13 +5,13 @@ pt-BR:
     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
     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á.
     contact: Contato
     contact_missing: Não definido
-    contact_unavailable: N/A
-    description_headline: O que é %{domain}?
-    domain_count_after: outras instâncias
-    domain_count_before: Conectado a
+    contact_unavailable: Não disponível
+    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>
@@ -28,25 +28,41 @@ pt-BR:
     hosted_on: Mastodon hospedado em %{domain}
     learn_more: Saiba mais
     other_instances: Lista de instâncias
+    privacy_policy: Política de Privacidade
     source_code: Código-fonte
-    status_count_after: publicações
+    status_count_after:
+      one: status
+      other: status
     status_count_before: Autores de
-    user_count_after: usuários
+    terms: Termos de serviço
+    user_count_after:
+      one: usuário
+      other: usuários
     user_count_before: Casa de
     what_is_mastodon: O que é Mastodon?
   accounts:
+    choices_html: 'Escolhas de %{name}:'
     follow: Seguir
-    followers: Seguidores
+    followers:
+      one: Seguidor
+      other: Seguidores
     following: Seguindo
+    joined: Participa desde %{date}
+    last_active: última atividade
+    link_verified_on: A posse desse link foi checada em %{date}
     media: Mídia
     moved_html: "%{name} se mudou 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 que %{name} segue
     people_who_follow: Pessoas que seguem %{name}
-    posts: Toots
+    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
-    remote_follow: Siga remotamente
     reserved_username: Este usuário está reservado
     roles:
       admin: Administrador
@@ -54,6 +70,9 @@ pt-BR:
       moderator: Moderador
     unfollow: Deixar de seguir
   admin:
+    account_actions:
+      action: Tomar uma ação
+      title: Realizar uma ação de moderação em %{acct}
     account_moderation_notes:
       create: Criar uma advertência
       created_msg: Nota de moderação criada com sucesso!
@@ -73,6 +92,7 @@ pt-BR:
       confirm: Confirmar
       confirmed: Confirmado
       confirming: Confirmando
+      deleted: Excluído
       demote: Rebaixar
       disable: Desativar
       disable_two_factor_authentication: Desativar 2FA
@@ -88,8 +108,11 @@ pt-BR:
       followers: Seguidores
       followers_url: URL de seguidores
       follows: Segue
+      header: Cabeçalho
       inbox_url: URL da caixa de entrada
+      invited_by: Convidado por
       ip: IP
+      joined: Se cadastrou
       location:
         all: Todos
         local: Local
@@ -99,6 +122,7 @@ pt-BR:
       media_attachments: Mídia(s) anexada(s)
       memorialize: Tornar um memorial
       moderation:
+        active: Ativo
         all: Todos
         silenced: Silenciados
         suspended: Suspensos
@@ -106,20 +130,18 @@ pt-BR:
       moderation_notes: Notas de moderação
       most_recent_activity: Atividade mais recente
       most_recent_ip: IP mais recente
+      no_limits_imposed: Nenhum limite imposto
       not_subscribed: Não está inscrito
-      order:
-        alphabetic: Alfabética
-        most_recent: Mais recente
-        title: Ordem
       outbox_url: URL da caixa de saída
-      perform_full_suspension: Aplicar suspensão total
+      perform_full_suspension: Suspender
       profile_url: URL do perfil
       promote: Promover
       protocol: Protocolo
       public: Público
       push_subscription_expires: Inscrição PuSH expira
-      redownload: Atualizar avatar
+      redownload: Atualizar perfil
       remove_avatar: Remover avatar
+      remove_header: Remover cabeçalho
       resend_confirmation:
         already_confirmed: Este usuário já está confirmado
         send: Re-enviar o e-mail de confirmação
@@ -138,27 +160,31 @@ pt-BR:
       shared_inbox_url: URL da caixa de entrada compartilhada
       show:
         created_reports: Denúncias criadas por esta conta
-        report: relatórios
         targeted_reports: Denúncias feitas sobre esta conta
       silence: Silenciar
+      silenced: Silenciado
       statuses: Postagens
       subscribe: Inscrever-se
+      suspended: Suspenso
       title: Contas
       unconfirmed_email: E-mail não confirmado
       undo_silenced: Retirar silenciamento
       undo_suspension: Retirar suspensão
       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"
         change_email_user: "%{name} mudou o endereço de e-mail do usuário %{target}"
         confirm_user: "%{name} confirmou o endereço de e-mail do usuário %{target}"
+        create_account_warning: "%{name} enviou um aviso para %{target}"
         create_custom_emoji: "%{name} enviou o emoji novo %{target}"
         create_domain_block: "%{name} bloqueou o domínio %{target}"
         create_email_domain_block: "%{name} colocou o domínio de e-mail %{target} na lista negra"
         demote_user: "%{name} rebaixou o usuário %{target}"
+        destroy_custom_emoji: "%{name} destruiu emoji %{target}"
         destroy_domain_block: "%{name} desbloqueou o domínio %{target}"
         destroy_email_domain_block: "%{name} retirou o domínio de e-mail %{target} da lista negra"
         destroy_status: "%{name} removeu postagem feita por %{target}"
@@ -180,6 +206,7 @@ pt-BR:
         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: "(status deletado)"
       title: Auditar relatório
     custom_emojis:
       by_domain: Domínio
@@ -206,8 +233,30 @@ pt-BR:
       update_failed_msg: Não foi possível atualizar esse emoji
       updated_msg: Emoji atualizado com sucesso!
       upload: Enviar
+    dashboard:
+      backlog: tarefas na fila
+      config: Configuração
+      feature_deletions: Remoção de contas
+      feature_invites: Convites
+      feature_profile_directory: Diretório de perfis
+      feature_registrations: Cadastros
+      feature_relay: Repetidor da federação
+      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
+      trends: Tendências
+      week_interactions: interações essa semana
+      week_users_active: ativos essa semana
+      week_users_new: usuários essa semana
     domain_blocks:
-      add_new: Adicionar novo
+      add_new: Adicionar novo bloqueio de domínio
       created_msg: Bloqueio de domínio está sendo processado
       destroyed_msg: Bloqueio de domínio desfeito
       domain: Domínio
@@ -222,11 +271,13 @@ pt-BR:
         title: Novo bloqueio de domínio
       reject_media: Rejeitar arquivos de mídia
       reject_media_hint: Remove arquivos de mídia armazenados localmente e recusa quaisquer outros no futuro. Irrelevante para suspensões
-      severities:
-        noop: Nenhum
-        silence: Silêncio
-        suspend: Suspensão
-      severity: Rigidez
+      reject_reports: Rejeitar denúncias
+      reject_reports_hint: Ignorar todas as denúncias vindas deste domíno. Irrelevante para suspensões
+      rejecting_media: rejeitando arquivos de mídia
+      rejecting_reports: rejeitando denúncias
+      severity:
+        silence: silenciado
+        suspend: suspenso
       show:
         affected_accounts:
           one: Uma conta no banco de dados foi afetada
@@ -236,8 +287,7 @@ pt-BR:
           suspend: Retirar suspensão de todas as contas neste domínio
         title: Retirar bloqueio de domínio de %{domain}
         undo: Retirar
-      title: Bloqueios de domínio
-      undo: Retirar
+      undo: Retirar bloqueio de domínio
     email_domain_blocks:
       add_new: Adicionar novo
       created_msg: Bloqueio de domínio de e-mail criado com sucesso
@@ -248,19 +298,47 @@ pt-BR:
         create: Adicionar domínio
         title: Novo bloqueio de domínio de e-mail
       title: Bloqueio de Domínio de E-mail
+    followers:
+      back_to_account: Voltar para a conta
+      title: Pessoas que seguem %{acct}
     instances:
-      account_count: Contas conhecidas
-      domain_name: Domínio
-      reset: Resetar
-      search: Buscar
-      title: Instâncias conhecidas
+      delivery_available: Entrega está disponível
+      known_accounts:
+        one: "%{count} conta conhecida"
+        other: "%{count} contas conhecidas"
+      moderation:
+        all: Todas
+        limited: Limitado
+        title: Moderação
+      title: Federação
+      total_blocked_by_us: Bloqueado por nós
+      total_followed_by_them: Seguidos por eles
+      total_followed_by_us: Seguidos por nós
+      total_reported: Denúncias sobre eles
+      total_storage: Mídias anexadas
     invites:
+      deactivate_all: Desativar todos
       filter:
         all: Todos
         available: Disponíveis
         expired: Expirados
         title: Filtro
       title: Convites
+    relays:
+      add_new: Adicionar novo repetidor
+      delete: Excluir
+      description_html: Um <strong>repetidor de federação</strong> é um servidor intermediário que troca um grande volume de toots públicos entre servidores que se inscrevem e publicam nele. <strong>O repetidor pode ser usado para ajudar servidores pequenos e médios a descobrir conteúdo do fediverso</strong>, que normalmente precisariam que usuários locais manualmente seguissem outras pessoas em servidores remotos.
+      disable: Desativar
+      disabled: Desabilitar
+      enable: Habilitar
+      enable_hint: Uma vez habilitado, seu servidor vai se inscrever para receber todos os toots públicos desse repetidor; E vai começar a enviar todos os toots públicos desse servidor para o repetidor.
+      enabled: Habilitado
+      inbox_url: URL do repetidor
+      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!
       destroyed_msg: Nota de denúncia excluída com sucesso!
@@ -275,7 +353,6 @@ pt-BR:
       comment:
         none: Nenhum
       created_at: Denunciado
-      id: ID
       mark_as_resolved: Marcar como resolvido
       mark_as_unresolved: Marcar como não resolvido
       notes:
@@ -286,20 +363,15 @@ pt-BR:
         placeholder: Descreva que ações foram tomadas, ou quaisquer outras atualizações relacionadas…
       reopen: Reabrir denúncia
       report: 'Denúncia #%{id}'
-      report_contents: Conteúdos
       reported_account: Conta denunciada
       reported_by: Denunciada por
       resolved: Resolvido
       resolved_msg: Denúncia resolvida com sucesso!
-      silence_account: Silenciar conta
       status: Status
-      suspend_account: Suspender conta
-      target: Alvo
       title: Denúncias
       unassign: Desatribuir
       unresolved: Não resolvido
       updated_at: Atualizado
-      view: Visualizar
     settings:
       activity_api_enabled:
         desc_html: Contagem de status postados localmente, usuários ativos e novos cadastros filtrados semanalmente
@@ -310,15 +382,24 @@ pt-BR:
       contact_information:
         email: E-mail
         username: Contate usuário
+      custom_css:
+        desc_html: Modificar o visual com CSS que é carregado em todas as páginas
+        title: CSS customizado
       hero:
         desc_html: Aparece na página inicial. Ao menos 600x100px é recomendado. Se não estiver definido, o thumbnail da instância é usado no lugar
         title: Imagem de capa
+      mascot:
+        desc_html: Mostrado em diversas páginas. Ao menos 293×205px recomendado. Quando não está configurado, o mascote padrão é mostrado
+        title: Imagem do mascote
       peers_api_enabled:
         desc_html: Nomes de domínio que essa instância encontrou no fediverso
         title: Publicar lista de instâncias descobertas
       preview_sensitive_media:
         desc_html: A pré-visualização do link em outros sites vai incluir uma miniatura mesmo se a mídia estiver marcada como sensível
         title: Mostrar mídia sensível em pré-visualizações OpenGraph
+      profile_directory:
+        desc_html: Permitir que usuários possam ser descobertos
+        title: Ativar diretório de perfis
       registrations:
         closed_message:
           desc_html: Exibido na página inicial quando cadastros estão fechados. Você pode usar tags HTML
@@ -339,11 +420,14 @@ pt-BR:
         desc_html: Mostrar uma insígnia de Equipe na página de usuário
         title: Mostrar insígnia de equipe
       site_description:
-        desc_html: Parágrafo introdutório na página inicial e em meta tags. Você pode usar tags HTML, em especial <code>&lt;a&gt;</code> e <code>&lt;em&gt;</code>.
+        desc_html: Parágrafo introdutório na página inicial. Descreva o que faz esse servidor especial, e qualquer outra coisa de importante. Você pode usar tags HTML, em especial <code>&lt;a&gt;</code> e <code>&lt;em&gt;</code>.
         title: Descrição da instância
       site_description_extended:
         desc_html: Um ótimo lugar para seu código de conduta, regras, diretrizes e outras coisas para diferenciar a sua instância. Você pode usar tags HTML
         title: Informação estendida customizada
+      site_short_description:
+        desc_html: Aparece na barra lateral e nas meta tags. Descreva o que é Mastodon e o que faz esse servidor especial em um único parágrafo. Se não for preenchido, é substituído pela descrição da instância.
+        title: Descrição curta da instância
       site_terms:
         desc_html: Você pode escrever a sua própria política de privacidade, termos de serviço, entre outras coisas. Você pode usar tags HTML
         title: Termos de serviço customizados
@@ -365,6 +449,7 @@ pt-BR:
       media:
         title: Mídia
       no_media: Não há mídia
+      no_status_selected: Nenhum status foi modificado porque nenhum estava selecionado
       title: Postagens da conta
       with_media: Com mídia
     subscriptions:
@@ -374,7 +459,21 @@ pt-BR:
       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
+    warning_presets:
+      add_new: Adicionar um novo
+      delete: Excluir
+      edit: Editar
+      edit_preset: Editar o aviso pré-definido
+      title: Gerenciar os avisos pré-definidos
   admin_mailer:
     new_report:
       body: "%{reporter} denunciou %{target}"
@@ -452,6 +551,13 @@ pt-BR:
     success_msg: A sua conta foi excluída com sucesso
     warning_html: Apenas a exclusão de conteúdo desta instância em particular é garantida. Conteúdo que tenha sido largamente compartilhado muito provavelmente deixará traços. Servidores offline e servidores que se desinscreveram de suas atualizações não irão atualizar as suas bases de dados.
     warning_title: Disponibilidade de conteúdo disseminado
+  directories:
+    directory: Diretório de perfis
+    explanation: Descobrir usuários baseado em seus interesses
+    explore_mastodon: Explorar %{title}
+    people:
+      one: "%{count} pessoa"
+      other: "%{count} pessoas"
   errors:
     '403': Você não tem permissão para ver esta página.
     '404': A página pela qual você está procurando não existe.
@@ -463,7 +569,7 @@ pt-BR:
     '500':
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">apps nativos</a> para o Mastodon em sua plataforma.
+    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.
   exports:
     archive_takeout:
       date: Data
@@ -474,7 +580,9 @@ pt-BR:
       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
   filters:
@@ -505,9 +613,13 @@ pt-BR:
     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:
     changes_saved_msg: Mudanças salvas com sucesso!
-    powered_by: graças a tecnologia de %{link}
+    copy: Copiar
     save_changes: Salvar mudanças
     validation_errors:
       one: Algo não está certo! Por favor, reveja o erro abaixo
@@ -543,8 +655,6 @@ pt-BR:
       expires_at: Expira em
       uses: Usos
     title: Convidar pessoas
-  landing_strip_html: "<strong>%{name}</strong> é um usuário no %{link_to_root_path}. Você pode segui-lo ou interagir com ele se você tiver uma conta em qualquer lugar no fediverso."
-  landing_strip_signup_html: Se não, você pode <a href="%{sign_up_path}">se cadastrar aqui</a>.
   lists:
     errors:
       limit: Você alcançou o número máximo de listas
@@ -616,15 +726,30 @@ pt-BR:
     publishing: Publicação
     web: Web
   remote_follow:
-    acct: Insira o seu usuário@domínio do qual você quer seguir
+    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
     no_account_html: Não tem uma conta? Você pode <a href='%{sign_up_path}' target='_blank'>cadastrar-se aqui</a>
     proceed: Prosseguir para seguir
     prompt: 'Você irá seguir:'
+    reason_html: "<strong>Por que esse passo é necessário?</strong> <code>%{instance}</code> pode não ser o servidor onde você se registrou, então precisamos redirecionar você para o seu servidor primeiro."
+  remote_interaction:
+    favourite:
+      proceed: Proceder para favoritar
+      prompt: 'Você quer favoritar este toot:'
+    reblog:
+      proceed: Proceder para compartilhar
+      prompt: 'Você quer compartilhar esse toot:'
+    reply:
+      proceed: Proceder para responder
+      prompt: 'Você quer responder à esse toot:'
   remote_unfollow:
     error: Erro
     title: Título
     unfollowed: Deixou de seguir
+  scheduled_statuses:
+    over_daily_limit: Você excedeu o limite de %{limit} toots planejados para esse dia
+    over_total_limit: Você excedeu o limite de %{limit} toots planejados
+    too_soon: A data planejada precisa ser no futuro
   sessions:
     activity: Última atividade
     browser: Navegador
@@ -704,6 +829,7 @@ pt-BR:
       private: Toot não-público não pode ser fixado
       reblog: Um compartilhamento não pode ser fixado
     show_more: Mostrar mais
+    sign_in_to_participate: Entre para participar dessa conversa
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Apenas seguidores
@@ -713,7 +839,6 @@ pt-BR:
       unlisted: Não listado
       unlisted_long: Todos podem ver, porém não será postado nas timelines públicas
   stream_entries:
-    click_to_show: Clique para mostrar
     pinned: Toot fixado
     reblogged: compartilhou
     sensitive_content: Conteúdo sensível
@@ -807,6 +932,7 @@ pt-BR:
   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
     description_html: Se você ativar a <strong>autenticação em dois passos</strong>, o acesso à sua conta exigirá posse de seu celular, que irá gerar tokens para validação.
@@ -828,6 +954,22 @@ pt-BR:
       explanation: Você pediu um backup completo da sua conta no Mastodon. E agora está pronto para ser baixado!
       subject: Seu arquivo está pronto para ser baixado
       title: Baixar arquivo
+    warning:
+      explanation:
+        disable: Enquanto sua conta está congelada, seus dados estão intactos, mas você não pode realizar nenhuma ação até que sua conta seja desbloqueada.
+        silence: Enquanto sua conta está limitada, somente pessoas que já estão seguindo você poderão ver seus toots nesse servidor, e você pode ser excluído de diversas listagens públicas. No entanto, outros ainda podem seguir você manualmente.
+        suspend: Sua conta está suspensa e todos os seus toots e mídias foram irreversivelmente removidas desse servidor e de servidores onde você tinha seguidores.
+      review_server_policies: Revisar as políticas do servidor
+      subject:
+        disable: Sua conta %{acct} foi congelada
+        none: Aviso para %{acct}
+        silence: Sua conta %{acct} foi limitada
+        suspend: Sua conta %{acct} foi suspensa
+      title:
+        disable: Conta congelada
+        none: Aviso
+        silence: Conta limitada
+        suspend: Conta suspensa
     welcome:
       edit_profile_action: Configurar perfil
       edit_profile_step: Você pode customizar o seu perfil enviando um avatar, uma imagem de topo, mudando seu nome de exibição, dentre outros. Se você gostaria de aprovar novos seguidores antes que eles possam seguir você, você pode trancar a sua conta.
@@ -839,7 +981,6 @@ pt-BR:
       review_preferences_action: Mudar as preferências
       review_preferences_step: Não se esqueça de configurar suas preferências, como quais e-mails você gostaria de receber, que nível de privacidade você gostaria que seus posts tenham por padrão. Se você não sofre de enjôo com movimento, você pode habilitar GIFs animando automaticamente.
       subject: Boas-vindas ao Mastodon
-      tip_bridge_html: Se você está vindo do Twitter, você pode encontrar pessoas conhecidas que estão no Mastodon usando <a href="%{bridge_url}">app de associação</a>. Mas só funciona se as pessoas também estiverem usando o app!
       tip_federated_timeline: A timeline global é uma visão contínua da rede do Mastodon. Mas ela só inclui pessoas que outras pessoas da sua instância estão seguindo, então não é a rede completa.
       tip_following: Você vai seguir administrador(es) da sua instância por padrão. Para encontrar mais gente interessante, confira as timelines local e global.
       tip_local_timeline: A timeline local é uma visão contínua das pessoas que estão em %{instance}. Esses são seus vizinhos próximos!
@@ -847,8 +988,12 @@ pt-BR:
       tips: Dicas
       title: Boas-vindas a bordo, %{name}!
   users:
+    follow_limit_reached: Você não pode seguir mais 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 você perder o acesso à ambos, você pode entrar em contato com %{email}
     seamless_external_login: Você está logado usando um serviço externo, então configurações de e-mail e senha não estão disponíveis.
     signed_in_as: 'Acesso como:'
+  verification:
+    explanation_html: 'Você pode <strong>verificar-se como tendo posse dos links nos metadados do seu perfil</strong>. Para isso, o site conectado deve conter um link de volta para o seu perfil do Mastodon. O link de volta <strong>deve</strong> conter um atributo <code>rel="me"</code>. O conteúdo ou texto do link não importa. Aqui está um exemplo:'
+    verification: Verificação
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index e113e67827a46512a610fdc387c77f4ea2c0dc0a..00f45588b67ab35ebf9a755235f1f601060ea564 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -8,9 +8,6 @@ pt:
     contact: Contacto
     contact_missing: Não configurado
     contact_unavailable: n.d.
-    description_headline: O que é o %{domain}?
-    domain_count_after: outras instâncias
-    domain_count_before: Ligado a
     extended_description_html: |
       <h3>Um bom lugar para regras</h3>
       <p>A descrição estendida ainda não foi configurada.</p>
@@ -44,7 +41,6 @@ pt:
     people_who_follow: Pessoas que seguem %{name}
     posts: Posts
     posts_with_replies: Posts e Respostas
-    remote_follow: Seguir remotamente
     reserved_username: Este nome de utilizadores é reservado
     roles:
       admin: Administrador
@@ -96,10 +92,6 @@ pt:
       most_recent_activity: Actividade mais recente
       most_recent_ip: IP mais recente
       not_subscribed: Não inscrito
-      order:
-        alphabetic: Alfabética
-        most_recent: Mais recente
-        title: Ordem
       outbox_url: URL da caixa de saída
       perform_full_suspension: Fazer suspensão completa
       profile_url: URL do perfil
@@ -126,7 +118,6 @@ pt:
       shared_inbox_url: URL da caixa de entrada compartilhada
       show:
         created_reports: Relatórios gerados por esta conta
-        report: relatórios
         targeted_reports: Relatórios feitos sobre esta conta
       silence: Silêncio
       statuses: Status
@@ -154,7 +145,7 @@ 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}"
-        reset_password_user: "%{name} restabeleceu a palavra-passe do utilizador %{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}"
@@ -204,11 +195,6 @@ 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
-      severities:
-        noop: Nenhum
-        silence: Silenciar
-        suspend: Suspender
-      severity: Severidade
       show:
         affected_accounts:
           one: Uma conta na base de dados afectada
@@ -218,7 +204,6 @@ pt:
           suspend: Não suspender todas as contas existentes nesse domínio
         title: Remover o bloqueio de domínio de %{domain}
         undo: Anular
-      title: Bloqueio de domínio
       undo: Anular
     email_domain_blocks:
       add_new: Adicionar novo
@@ -231,10 +216,6 @@ pt:
         title: Novo bloqueio de domínio de email
       title: Bloqueio de Domínio de Email
     instances:
-      account_count: Contas conhecidas
-      domain_name: Domínio
-      reset: Restaurar
-      search: Pesquisar
       title: Instâncias conhecidas
     invites:
       filter:
@@ -248,20 +229,14 @@ pt:
       are_you_sure: Tens a certeza?
       comment:
         none: Nenhum
-      id: ID
       mark_as_resolved: Marcar como resolvido
       report: 'Denúncia #%{id}'
-      report_contents: Conteúdos
       reported_account: Conta denunciada
       reported_by: Denúnciada por
       resolved: Resolvido
-      silence_account: Conta silenciada
       status: Estado
-      suspend_account: Conta suspensa
-      target: Alvo
       title: Denúncias
       unresolved: Por resolver
-      view: Ver
     settings:
       activity_api_enabled:
         desc_html: Contagem semanais de publicações locais, utilizadores activos e novos registos
@@ -409,7 +384,7 @@ pt:
     '500':
       content: Desculpe, mas algo correu mal.
       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="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">apps nativos</a> para o Mastodon na sua plataforma.
+    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:
     blocks: Bloqueaste
     csv: CSV
@@ -430,7 +405,6 @@ pt:
     unlocked_warning_title: A tua conta não está bloqueada
   generic:
     changes_saved_msg: Alterações guardadas!
-    powered_by: fornecido por %{link}
     save_changes: Guardar alterações
     validation_errors:
       one: Algo não está correcto. Por favor vê o erro abaixo
@@ -464,8 +438,6 @@ pt:
       expires_at: Expira
       uses: Usos
     title: Convidar pessoas
-  landing_strip_html: "<strong>%{name}</strong> é um utilizador em %{link_to_root_path}. Podes segui-lo ou interagir com ele se tiveres uma conta em qualquer lugar no fediverso."
-  landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
   lists:
     errors:
       limit: Número máximo de listas alcançado
@@ -612,7 +584,6 @@ pt:
       unlisted: Público, mas não mostre no timeline público
       unlisted_long: Todos podem ver, porém não será postado nas timelines públicas
   stream_entries:
-    click_to_show: Clique pra mostrar
     pinned: Toot fixado
     reblogged: boosted
     sensitive_content: Conteúdo sensível
diff --git a/config/locales/ro.yml b/config/locales/ro.yml
new file mode 100644
index 0000000000000000000000000000000000000000..aa4d3c967c485039b4248d30a6bad8ddd2e662d5
--- /dev/null
+++ b/config/locales/ro.yml
@@ -0,0 +1,121 @@
+---
+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
+    delete_account_html: Dacă vrei să ștergi acest cont <a href="%{path}">poți începe aici</a>. Va trebui să confirmi această acțiune.
+    didnt_get_confirmation: Nu ai primit instrucțiunile de confirmare?
+    forgot_password: Ai uitat parola?
+    invalid_reset_password_token: Această cerere este invalidă sau a expirat. Încearcă resetarea parolei din nou.
+    login: Conectare
+    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
+    set_new_password: Setează o nouă parolă
+  authorize_follow:
+    already_following: Urmărești deja acest cont
+    error: Din păcate a apărut o eroare
+    follow: Urmărește
+    follow_request: 'Ai trimis o cerere de urmărire către:'
+    following: 'Gata! De acum urmărești:'
+    post_follow:
+      close: Sau, poți închide această fereastră.
+      return: Arată profilul utilizatorului
+      web: Mergi la web
+    title: Urmărește %{acct}
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count}o"
+      about_x_months: "%{count}l"
+      about_x_years: "%{count}ani"
+      almost_x_years: "%{count}ani"
+      half_a_minute: Chiar acum
+      less_than_x_minutes: "%{count}l"
+      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
+    description_html: Această acțiune este <strong>permanentă și ireversibilă,</strong> elimină conținutul și dezactivează contul tău. Acest username va rămâne permanent rezervat pentru a evita furtul de identitate.
+    proceed: Șterge contul
+    success_msg: Contul tău a fost șterg. Nu mai poate fi recuperat :D
+    warning_html: Doar ștergerea conținutului de pe acest server este garantată. Conținutul tău care a fost redistribuit în alte instațe e posibil să lase urme. Serverele deconecate sau care nu mai sunt abonate la actualizările contului tău nu își vor mai actualiza baza de date.
+  directories:
+    explanation: Descoperă oameni și companii în funcție de interesele lor
+    explore_mastodon: Explorează %{title}
+    people:
+      few: "%{count} persoană"
+      one: "%{count} persoană"
+      other: "%{count} oameni"
+  errors:
+    '403': Nu ai permisiunea să vizitezi această pagină.
+    '404': Pagina pe care o cauți nu există.
+    '410': Pagina pe care o cauți nu mai există.
+    '422':
+      content: Verificarea securității a eșuat. Ai blocat cookiurile?
+      title: Verificarea securității a eșuat
+    '429': Strangulat
+    '500':
+      content: Ne pare rău, dar ceva a funcționat greșit. Încercați din nou!?
+      title: Această pagină nu este corectă
+    noscript_html: Pentru a utiliza o aplicație web Mastodon, te rog activează JavaScript. Alternativ, încearcă una din <a href="%{apps_path}">aplicațiile native</a> Mastodon pentru platforma ta.
+  exports:
+    archive_takeout:
+      date: Data
+      download: Descarcă arhiva contului tău
+      hint_html: Poți solicita arhiva<strong>postărilor și conținutul media</strong> a contului tău. Datele furnizate sunt în formatul ActivityPub. Poți solicita cate o arhivă la 7 zile.
+      in_progress: Pregătim arhiva ta...
+      request: Cere arhiva ta
+      size: Dimensiune
+    blocks: Blocați
+    csv: CSV
+    follows: Tu urmărești
+    mutes: Opriți
+    storage: Depozitare media
+  filters:
+    contexts:
+      home: Fluxul Acasă
+      notifications: Notificări
+      public: Fluxul public
+      thread: Conversații
+    edit:
+      title: Editează filtru
+    errors:
+      invalid_context: Lipsa conținut sau acesta este invalid
+      invalid_irreversible: Filtrarea ireversibilă funcționează dor cu context din fluxul Acasă și notificări
+    index:
+      delete: Șterge
+      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
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index f6bbfd7fb1bcfd0db11807c9f8feb9ebf3fc54e5..40765447b5624ae39d5142171b9605f0b79a4e40 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -5,13 +5,12 @@ ru:
     about_mastodon_html: Mastodon - это <em>свободная</em> социальная сеть с <em>открытым исходным кодом</em>. Как <em>децентрализованная</em> альтернатива коммерческим платформам, Mastodon предотвращает риск монополизации Вашего общения одной компанией. Выберите сервер, которому Вы доверяете &mdash; что бы Вы ни выбрали, Вы сможете общаться со всеми остальными. Любой может запустить свой собственный узел Mastodon и участвовать в <em>социальной сети</em> совершенно бесшовно.
     about_this: Об этом узле
     administered_by: 'Администратор узла:'
-    closed_registrations: В данный момент регистрация на этом узле закрыта.
+    api: API
+    apps: Приложения
+    closed_registrations: В данный момент регистрация на этом узле закрыта. Но вы можете найти другой узел, создать на нём учётную запись и получить доступ к той же сети оттуда.
     contact: Связаться
     contact_missing: Не установлено
     contact_unavailable: Недоступен
-    description_headline: Что такое %{domain}?
-    domain_count_after: другими узлами
-    domain_count_before: Связан с
     extended_description_html: |
       <h3>Хорошее место для правил</h3>
       <p>Расширенное описание еще не настроено.</p>
@@ -28,25 +27,47 @@ ru:
     hosted_on: Mastodon размещен на %{domain}
     learn_more: Узнать больше
     other_instances: Другие узлы
+    privacy_policy: Политика конфиденциальности
     source_code: Исходный код
-    status_count_after: статусов
+    status_count_after:
+      few: статуса
+      many: статусов
+      one: статус
+      other: статусов
     status_count_before: Опубликовано
-    user_count_after: пользователей
+    terms: Условия использования
+    user_count_after:
+      few: пользователя
+      many: пользователей
+      one: пользователь
+      other: пользователей
     user_count_before: Здесь живет
     what_is_mastodon: Что такое Mastodon?
   accounts:
+    choices_html: "%{name} рекомендует:"
     follow: Подписаться
-    followers: Подписчики
-    following: Подписан(а)
-    media: Медиаконтент
+    followers:
+      few: подписчика
+      many: подписчиков
+      one: подписчик
+      other: подписчиков
+    following: подписки
+    joined: 'Дата регистрации: %{date}'
+    media: Медиа
     moved_html: "%{name} переехал(а) на %{new_profile_link}:"
     network_hidden: Эта информация недоступна
     nothing_here: Здесь ничего нет!
     people_followed_by: Люди, на которых подписан(а) %{name}
     people_who_follow: Подписчики %{name}
-    posts: Посты
+    pin_errors:
+      following: Чтобы порекомендовать кого-то, надо сначала на них подписаться
+    posts:
+      few: статуса
+      many: статусов
+      one: статус
+      other: статусов
+    posts_tab_heading: Статусы
     posts_with_replies: Посты с ответами
-    remote_follow: Подписаться на удаленном узле
     reserved_username: Имя пользователя зарезервировано
     roles:
       admin: Администратор
@@ -107,10 +128,6 @@ ru:
       most_recent_activity: Последняя активность
       most_recent_ip: Последний IP
       not_subscribed: Не подписаны
-      order:
-        alphabetic: По алфавиту
-        most_recent: По дате
-        title: Порядок
       outbox_url: URL исходящих
       perform_full_suspension: Полная блокировка
       profile_url: URL профиля
@@ -138,7 +155,6 @@ ru:
       shared_inbox_url: URL общих входящих
       show:
         created_reports: Жалобы, отправленные этим аккаунтом
-        report: жалоба
         targeted_reports: Жалобы на этот аккаунт
       silence: Глушение
       statuses: Статусы
@@ -180,11 +196,12 @@ ru:
         unsuspend_account: "%{name} разморозил(а) аккаунт %{target}"
         update_custom_emoji: "%{name} обновил(а) эмодзи %{target}"
         update_status: "%{name} изменил(а) статус пользователя %{target}"
+      deleted_status: "(удалённый статус)"
       title: Журнал событий
     custom_emojis:
       by_domain: Домен
       copied_msg: Локальная копия эмодзи успешно создана
-      copy: Скопироват
+      copy: Копировать
       copy_failed_msg: Не удалось создать локальную копию эмодзи
       created_msg: Эмодзи успешно создано!
       delete: Удалить
@@ -206,6 +223,27 @@ ru:
       update_failed_msg: Невозможно обновить этот эмодзи
       updated_msg: Эмодзи обновлён!
       upload: Загрузить
+    dashboard:
+      backlog: задачи
+      config: Конфигурация
+      feature_deletions: Удаление аккаунтов
+      feature_invites: Пригласительные ссылки
+      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: Блокировка домена обрабатывается
@@ -221,12 +259,7 @@ ru:
           suspend: Блокировка
         title: Новая доменная блокировка
       reject_media: Запретить медиаконтент
-      reject_media_hint: Удаляет локально хранимый медиаконтент и запрещает его загрузку в будущем. Не имеет значения в случае блокировки.
-      severities:
-        noop: Ничего
-        silence: Глушение
-        suspend: Блокировка
-      severity: Строгость
+      reject_media_hint: Удаляет локально хранимый медиаконтент и запрещает его загрузку в будущем. Не имеет значения в случае блокировки
       show:
         affected_accounts:
           few: Влияет на %{count} аккаунта в базе данных
@@ -238,7 +271,6 @@ ru:
           suspend: Снять блокировку со всех существующих аккаунтов этого домена
         title: Снять блокировку с домена %{domain}
         undo: Отменить
-      title: Доменные блокировки
       undo: Отменить
     email_domain_blocks:
       add_new: Добавить новую
@@ -251,18 +283,25 @@ ru:
         title: Новая доменная блокировка еmail
       title: Доменная блокировка email
     instances:
-      account_count: Известных аккаунтов
-      domain_name: Домен
-      reset: Сбросить
-      search: Поиск
       title: Известные узлы
     invites:
+      deactivate_all: Отключить все
       filter:
         all: Все
         available: Актуальные
         expired: Истёкшие
         title: Фильтр
       title: Приглашения
+    relays:
+      add_new: Добавить ретранслятор
+      description_html: "<strong>Федеративный ретранслятор</strong> – это промежуточный сервер, который передаёт большие объёмы публичных статусов между серверами, которые подписываются и публикуют туда. <strong>Это может помочь небольшим и средним серверам находить записи со всей федерации</strong>, ведь в противном случае пользователям нужно будет вручную подписываться на людей с удалённых узлов."
+      enable_hint: Если включено, ваш сервер будет подписан на все публичные статусы с этого ретранслятора и начнёт туда отправлять публичные статусы со своего узла.
+      inbox_url: URL ретранслятора
+      pending: Ожидание подтверждения ретранслятора
+      save_and_enable: Сохранить и включить
+      setup: Настроить соединение с ретранслятором
+      status: Состояние
+      title: Ретрансляторы
     report_notes:
       created_msg: Примечание жалобы создано!
       destroyed_msg: Примечание жалобы удалено!
@@ -277,31 +316,25 @@ ru:
       comment:
         none: Нет
       created_at: Создано
-      id: ID
       mark_as_resolved: Отметить как разрешенную
       mark_as_unresolved: Отметить как неразрешённую
       notes:
         create: Добавить заметку
-        create_and_resolve: Разрешить с заметкой
-        create_and_unresolve: Переоткрыть с заметкой
+        create_and_resolve: Разрешить с примечанием
+        create_and_unresolve: Переоткрыть с примечанием
         delete: Удалить
         placeholder: Опишите, какие действия были приняты, или любые другие подробности…
       reopen: Переоткрыть жалобу
       report: 'Жалоба #%{id}'
-      report_contents: Содержимое
       reported_account: Аккаунт нарушителя
       reported_by: Отправитель жалобы
       resolved: Разрешено
       resolved_msg: Жалоба успешно обработана!
-      silence_account: Заглушить аккаунт
       status: Статус
-      suspend_account: Блокировать аккаунт
-      target: Цель
       title: Жалобы
       unassign: Снять назначение
       unresolved: Неразрешенные
       updated_at: Обновлена
-      view: Просмотреть
     settings:
       activity_api_enabled:
         desc_html: Подсчёт количества локальных статусов, активных пользователей и новых регистраций на еженедельной основе
@@ -312,12 +345,18 @@ ru:
       contact_information:
         email: Введите публичный e-mail
         username: Введите имя пользователя
+      custom_css:
+        desc_html: Измените внешний вид с CSS, загружаемым на каждой странице
+        title: Особый CSS
       hero:
         desc_html: Отображается на главной странице. Рекомендуется разрешение не менее 600х100px. Если не установлено, используется изображение узла
         title: Баннер узла
       peers_api_enabled:
         desc_html: Домены, которые были замечены этим узлом среди всей федерации
         title: Публикация списка обнаруженных узлов
+      preview_sensitive_media:
+        desc_html: Предпросмотр ссылок с остальных веб-сайтов будет показан даже если медиаконтент отмечен как чувствительный
+        title: Показывать чувствительный медиаконтент в предпросмотре OpenGraph
       registrations:
         closed_message:
           desc_html: Отображается на титульной странице, когда закрыта регистрация<br>Можно использовать HTML-теги
@@ -327,7 +366,7 @@ ru:
           title: Разрешить удаление аккаунтов
         min_invite_role:
           disabled: Никого
-          title: Разрешает приглашения от
+          title: Разрешать приглашения от
         open:
           desc_html: Позволяет любому создавать аккаунт
           title: Открыть регистрацию
@@ -342,9 +381,12 @@ ru:
         title: Описание сайта
       site_description_extended:
         desc_html: Отображается на странице дополнительной информации<br>Можно использовать HTML-теги
-        title: Расширенное описание сайта
+        title: Расширенное описание узла
+      site_short_description:
+        desc_html: Отображается в боковой панели и в тегах. Опишите, что такое Mastodon и что делает именно этот узел особенным. Если пусто, используется описание узла по умолчанию.
+        title: Краткое описание узла
       site_terms:
-        desc_html: Вы можете добавить сюда собственную политику конфиденциальности, пользовательское соглашение и другие документы. Можно использовать теги HTML.
+        desc_html: Вы можете добавить сюда собственную политику конфиденциальности, пользовательское соглашение и другие документы. Можно использовать теги HTML
         title: Условия использования
       site_title: Название сайта
       thumbnail:
@@ -364,6 +406,7 @@ ru:
       media:
         title: Медиаконтент
       no_media: Без медиаконтента
+      no_status_selected: Не выбран ни один статус, ничего не изменено
       title: Статусы аккаунта
       with_media: С медиаконтентом
     subscriptions:
@@ -457,12 +500,12 @@ ru:
     '410': Страница, которую Вы искали, больше не существует.
     '422':
       content: Проверка безопасности не удалась. Возможно, Вы блокируете cookies?
-      title: Проверка безопасности не удалась.
+      title: Проверка безопасности не удалась
     '429': Слишком много запросов
     '500':
       content: Приносим извинения, но на нашей стороне что-то пошло не так.
       title: Страница неверна
-    noscript_html: Для работы с Mastodon, пожалуйста, включите JavaScript. Кроме того, вы можете использовать одно из <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">приложений</a> Mastodon для Вашей платформы.
+    noscript_html: Для работы с Mastodon, пожалуйста, включите JavaScript. Кроме того, вы можете использовать одно из <a href="%{apps_path}">приложений</a> Mastodon для Вашей платформы.
   exports:
     archive_takeout:
       date: Дата
@@ -476,6 +519,22 @@ ru:
     follows: Подписки
     mutes: Список глушения
     storage: Ваш медиаконтент
+  filters:
+    contexts:
+      home: Домашняя лента
+      notifications: Уведомления
+      public: Публичные ленты
+      thread: Диалоги
+    edit:
+      title: Изменить фильтр
+    errors:
+      invalid_context: Некорректный контекст или ничего
+      invalid_irreversible: Необратимая фильтрация работает только с лентой уведомлений и домашней лентой
+    index:
+      delete: Удалить
+      title: Фильтры
+    new:
+      title: Добавить фильтр
   followers:
     domain: Домен
     explanation_html: Если Вы хотите быть уверены в приватности Ваших статусов, Вы должны иметь четкое представление о том, кто на Вас подписан. <strong>Ваши приватные статусы отправляются всем узлам, на которых у Вас есть подписчики</strong>. Рекомендуем удалить из подписчиков пользователей узлов, администрации или программному обеспечению которых Вы не доверяете.
@@ -490,9 +549,12 @@ ru:
     true_privacy_html: Пожалуйста, заметьте, что <strong>настоящая конфиденциальность может быть достигнута только при помощи end-to-end шифрования</strong>.
     unlocked_warning_html: Кто угодно может подписаться на Вас и получить доступ к просмотру Ваших приватных статусов. %{lock_link}, чтобы получить возможность рассматривать и вручную подтверждать запросы о подписке.
     unlocked_warning_title: Ваш аккаунт не закрыт для подписки
+  footer:
+    developers: Разработчикам
+    more: Ещё…
+    resources: Ссылки
   generic:
     changes_saved_msg: Изменения успешно сохранены!
-    powered_by: работает на %{link}
     save_changes: Сохранить изменения
     validation_errors:
       few: Что-то здесь не так! Пожалуйста, прочитайте о %{count} ошибках ниже
@@ -523,16 +585,14 @@ ru:
     max_uses:
       few: "%{count} исп."
       many: "%{count} исп."
-      one: 1 исп.
-      other: "%{count} исп."
+      one: 1 исп
+      other: "%{count} исп"
     max_uses_prompt: Без лимита
-    prompt: Генерируйте и делитесь ссылками с другими, чтобы предоставить им доступ к этому узлу.
+    prompt: Генерируйте и делитесь ссылками с другими, чтобы предоставить им доступ к этому узлу
     table:
       expires_at: Истекает
       uses: Исп.
     title: Пригласить людей
-  landing_strip_html: "<strong>%{name}</strong> - пользователь на %{link_to_root_path}. Вы можете подписаться на него/нее и общаться с ним/ней, если у Вас есть аккаунт на любом узле общей сети."
-  landing_strip_signup_html: Если у Вас его нет, вы можете <a href="%{sign_up_path}">зарегистрироваться здесь</a>.
   lists:
     errors:
       limit: Вы достигли максимального числа списков
@@ -608,8 +668,9 @@ ru:
     publishing: Публикация
     web: WWW
   remote_follow:
-    acct: Введите username@domain, откуда Вы хотите подписаться
+    acct: Введите свой username@domain для продолжения
     missing_resource: Поиск требуемого перенаправления URL для Вашего аккаунта завершился неудачей
+    no_account_html: Нет учётной записи? Вы можете <a href='%{sign_up_path}' target='_blank'>зарегистрироваться здесь</a>
     proceed: Продолжить подписку
     prompt: 'Вы хотите подписаться на:'
   remote_unfollow:
@@ -692,6 +753,7 @@ ru:
       many: 'содержались запрещённые хэштеги: %{tags}'
       one: 'содержался запрещённый хэштег: %{tags}'
       other: 'содержались запрещённые хэштеги: %{tags}'
+    language_detection: Определять язык автоматически
     open_in_web: Открыть в WWW
     over_character_limit: превышен лимит символов (%{max})
     pin_errors:
@@ -699,7 +761,8 @@ ru:
       ownership: Нельзя закрепить чужой статус
       private: Нельзя закрепить непубличный статус
       reblog: Нельзя закрепить продвинутый статус
-    show_more: Подробнее
+    show_more: Ещё
+    sign_in_to_participate: Войдите, чтобы принять участие в дискуссии
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Для подписчиков
@@ -709,8 +772,7 @@ ru:
       unlisted: Скрывать из лент
       unlisted_long: Показывать всем, но не отображать в публичных лентах
   stream_entries:
-    click_to_show: Показать
-    pinned: Закреплённое сообщение
+    pinned: Закреплённый статус
     reblogged: продвинул(а)
     sensitive_content: Чувствительный контент
   terms:
@@ -831,7 +893,6 @@ ru:
       review_preferences_action: Изменить настройки
       review_preferences_step: Проверьте все настройки, например, какие письма Вы хотите получать или уровень приватности статусов по умолчанию. Если Вы не страдаете морской болезнь, можете включить автовоспроизведение GIF.
       subject: Добро пожаловать в Mastodon
-      tip_bridge_html: Если Вы пришли из Twitter, можете поискать своих друзей в Mastodon, используя <a href="%{bridge_url}">приложение-мост</a>. Но это работает только если они тоже использовали это приложение!
       tip_federated_timeline: В глобальной ленте отображается сеть Mastodon. Но в ней показаны посты только от людей, на которых подписаны Вы и Ваши соседи, поэтому лента может быть неполной.
       tip_following: По умолчанию Вы подписаны на администратора(-ов) Вашего узла. Чтобы найти других интересных людей, проверьте локальную и глобальную ленты.
       tip_local_timeline: В локальной ленте показаны посты от людей с %{instance}. Это Ваши непосредственные соседи!
diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml
index 5c0c0a57c820d3fbdf4c8b55c211832a844a13a4..ef1d269eeadb7626ad447d130c93287515d716e4 100644
--- a/config/locales/simple_form.ar.yml
+++ b/config/locales/simple_form.ar.yml
@@ -2,28 +2,37 @@
 ar:
   simple_form:
     hints:
+      account_warning_preset:
+        text: بإمكانك استخدام نفس القواعد التي نجدها في التبويقات كعناوين الروابط والوسوم والإشارات
+      admin_account_action:
+        send_email_notification: سوف يتلقى المستخدم رسالة تُفسِّر ما حدث على حسابه
+        type_html: اختر ما تود إجراؤه على <strong>%{acct}</strong>
+        warning_preset_id: اختياري. يمكنك إضافة نص مخصص إلى نهاية النموذج
       defaults:
         autofollow: سوف يتابعك تلقائيًا الأشخاص الذين يقومون بالتسجيل من خلال الدعوة
-        avatar: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 400x400px
+        avatar: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير %{size}. سيتم تصغيره إلى %{dimensions}px
         bot: يُعلِم أنّ هذا الحساب لا يمثل شخصًا
         context: واحد أو أكثر من السياقات التي يجب أن ينطبق عليها عامل التصفية
         digest: تُرسَل إليك بعد مُضيّ مدة مِن خمول نشاطك و فقط إذا ما تلقيت رسائل شخصية مباشِرة أثناء فترة غيابك مِن الشبكة
-        display_name:
-          one: <span class="name-counter">1</span> حرف باق
-          other: <span class="name-counter">%{count}</span> حرف باق
+        email: سوف تتلقى رسالة إلكترونية للتأكيد
         fields: يُمكنك عرض 4 عناصر على شكل جدول في ملفك الشخصي
-        header: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 700x335px
+        header: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير %{size}. سيتم تصغيره إلى %{dimensions}px
+        inbox_url: نسخ العنوان الذي تريد استخدامه مِن صفحة الإستقبال للمُرحَّل
         irreversible: التبويقات التي تم تصفيتها ستختفي لا محالة حتى و إن تمت إزالة عامِل التصفية لاحقًا
         locale: لغة واجهة المستخدم و الرسائل الإلكترونية و الإشعارات
         locked: يتطلب منك الموافقة يدويا على طلبات المتابعة
-        note:
-          one: <span class="note-counter">1</span> حرف باق
-          other: <span class="note-counter">%{count}</span> حرف باق
+        password: يُنصح باستخدام 8 أحرف على الأقل
+        phrase: سوف يتم العثور عليه مهما كان نوع النص أو حتى و إن كان داخل الويب فيه تحذير عن المحتوى
         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}
       imports:
         data: ملف CSV تم تصديره مِن مثيل خادوم ماستدون آخر
       sessions:
@@ -35,6 +44,18 @@ ar:
         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: الصورة الرمزية
@@ -45,11 +66,13 @@ ar:
         context: تصفية السياقات
         current_password: كلمة السر الحالية
         data: البيانات
+        discoverable: القيام بإدراج هذا الحساب في قائمة دليل الحسابات
         display_name: الإسم المعروض
         email: عنوان البريد الإلكتروني
         expires_in: تنتهي مدة صلاحيته بعد
-        fields: واصفات بيانات الملف الشخصي
+        fields: البيانات الوصفية للصفحة الشخصية
         header: الرأسية
+        inbox_url: عنوان رابط صندوق المُرَحِّل
         irreversible: إسقاط بدلا من إخفائها
         locale: لغة الواجهة
         locked: تجميد الحساب
@@ -59,13 +82,18 @@ ar:
         otp_attempt: رمز المصادقة بخطوتين
         password: كلمة السر
         phrase: كلمة مفتاح أو عبارة
+        setting_aggregate_reblogs: جمع الترقيات في خيوط زمنية
         setting_auto_play_gif: تشغيل تلقائي لِوَسائط جيف المتحركة
         setting_boost_modal: إظهار مربع حوار للتأكيد قبل ترقية أي تبويق
         setting_default_language: لغة النشر
         setting_default_privacy: خصوصية المنشور
         setting_default_sensitive: إعتبر الوسائط دائما كمحتوى حساس
         setting_delete_modal: إظهار مربع حوار للتأكيد قبل حذف أي تبويق
-        setting_display_sensitive_media: دائمًا إظهار الوسائط الحساسة
+        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: تخفيض عدد الصور في الوسائط المتحركة
@@ -76,6 +104,7 @@ ar:
         type: صيغة الإستيراد
         username: إسم المستخدم
         username_or_email: إسم المستخدم أو كلمة السر
+        whole_word: الكلمة كاملة
       interactions:
         must_be_follower: حظر الإخطارات القادمة من حسابات لا تتبعك
         must_be_following: حظر الإخطارات القادمة من الحسابات التي لا تتابعها
@@ -87,6 +116,7 @@ ar:
         follow_request: إبعث بريدا إلكترونيا عندما يقوم أحدهم بإرسال طلب بالمتابعة
         mention: إبعث بريداً إلكترونيًا عندما يُشير إليك أو يذكُرك أحدهم
         reblog: إبعث بريداً إلكترونيًا عندما يقوم أحدهم بترقية منشورك
+        report: إرسال رسالة إلكترونية عند تلقّي إبلاغ جديد
     'no': لا
     required:
       mark: "*"
diff --git a/config/locales/simple_form.ast.yml b/config/locales/simple_form.ast.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b91d5780a9d977087e51fd78d4c07281fa4a8ef8
--- /dev/null
+++ b/config/locales/simple_form.ast.yml
@@ -0,0 +1,66 @@
+---
+ast:
+  simple_form:
+    hints:
+      defaults:
+        autofollow: La xente que se rexistre pente la invitación va siguite automáticamente
+        bot: Esta cuenta fai principalmente aiciones automatizaes y podría nun supervisase
+        digest: Namái s'unvia tres un periodu llargu d'inactividá y namái si recibiesti cualesquier mensaxe personal na to ausencia
+        email: Vamos unviate un corréu de confirmación
+        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
+    labels:
+      account:
+        fields:
+          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
+        current_password: Contraseña actual
+        data: Datos
+        display_name: Nome a amosar
+        email: Direición de corréu
+        expires_in: Caduca tres
+        fields: Datos meta del perfil
+        header: Testera
+        irreversible: Escartar en cuentes d'anubrir
+        locale: Llingua de la interfaz
+        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
+        setting_auto_play_gif: Reproducir GIFs automáticamente
+        setting_default_language: Llingua de les espublizaciones
+        setting_default_privacy: Privacidá d'espublizaciones
+        setting_delete_modal: Amosar el diálogu de confirmación enantes de desaniciar un toot
+        setting_system_font_ui: Usar la fonte predeterminada del sistema
+        setting_unfollow_modal: Amosar el diálogu de confirmación enantes de dexar de siguir a daquién
+        severity: Severidá
+        type: Triba de la importación
+        username: Nome d'usuariu
+        username_or_email: Nome d'usuariu o corréu
+      interactions:
+        must_be_follower: Bloquiar avisos de persones que nun son siguidores
+        must_be_following: Bloquiar avisos de persones que nun sigues
+        must_be_following_dm: Bloquiar mensaxes direutos de persones que nun sigues
+      notification_emails:
+        favourite: Unviar un corréu cuando daquién conseñe como favoritu los tos estaos
+        follow: Unviar un corréu cuando daquién te siga
+        follow_request: Unviar un corréu cuando daquién solicite siguite
+        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 4c96ebc8633ef52ac6ccdb8761fd7b2ed32443ae..9441e53b3748ba62ce66b694f0c5b926cad00555 100644
--- a/config/locales/simple_form.bg.yml
+++ b/config/locales/simple_form.bg.yml
@@ -3,11 +3,9 @@ bg:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF или JPG. До 2MB. Ще бъде смалена до 400x400 пиксела
-        display_name: До 30 символа
-        header: PNG, GIF или JPG. До 2MB. Ще бъде смалена до 700x335 пиксела
+        avatar: PNG, GIF или JPG. До %{size}. Ще бъде смалена до %{dimensions} пиксела
+        header: PNG, GIF или JPG. До %{size}. Ще бъде смалена до %{dimensions} пиксела
         locked: Изисква ръчно одобрение на последователите. По подразбиране, публикациите са достъпни само до последователи.
-        note: До 65535 символа
       imports:
         data: CSV файл, експортиран от друга инстанция на Mastodon
     labels:
diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml
index 482ddd7bebccbdb1d51ac482c983b8366da55479..4c2b1636dcb535e5064dc8e60ee9dce8e30141ea 100644
--- a/config/locales/simple_form.ca.yml
+++ b/config/locales/simple_form.ca.yml
@@ -2,28 +2,40 @@
 ca:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Pots utilitzar totes les sintaxi com ara URL, etiquetes i mencions
+      admin_account_action:
+        send_email_notification: L'usuari rebrà una explicació del que ha passat amb el seu compte
+        text_html: Opcional. Pots utilitzar tota la sintaxi. Pots <a href="%{path}">afegir configuracions predefinides d'avís</a> per a estalviar temps
+        type_html: Tria què fer amb <strong>%{acct}</strong>
+        warning_preset_id: Opcional. Encara pots afegir text personalitzat al final de la configuració predefinida
       defaults:
         autofollow: Les persones que es registrin a través de la invitació et seguiran automàticament
-        avatar: PNG, GIF o JPG. Màxim 2MB. S'escalarà a 400x400px
+        avatar: PNG, GIF o JPG. Màxim %{size}. S'escalarà a %{dimensions}px
         bot: Aquest compte realitza principalment accions automatitzades i pot no estar controlat per cap persona
         context: Un o diversos contextos on s'ha d'aplicar el filtre
         digest: Només s'envia després d'un llarg període d'inactivitat amb un resum de les mencions que has rebut en la teva absència
-        display_name:
-          one: <span class="name-counter">1</span> càracter restant
-          other: <span class="name-counter">%{count}</span> càracters restans
+        discoverable_html: El <a href="%{path}" target="_blank">directori</a> permet trobar usuaris en funció dels interessos i activitat. Requereix almenys %{min_followers} seguidors
+        email: Se t'enviarà un correu electrònic de confirmació
         fields: Pots tenir fins a 4 elements que es mostren com a taula al teu perfil
-        header: PNG, GIF o JPG. Màxim 2MB. S'escalarà a 700x335px
+        header: PNG, GIF o JPG. Màxim %{size}. S'escalarà a %{dimensions}px
+        inbox_url: Copia l'URL des de la pàgina principal del relay que vols utilitzar
         irreversible: Els nodes filtrats desapareixeran de manera irreversible, fins i tot si el filtre es retira més tard
         locale: El llenguatge de l’interfície d’usuari, els correus i les notificacions push
         locked: Requereix que aprovis manualment els seguidors
-        note:
-          one: <span class="note-counter">1</span> càracter restant
-          other: <span class="note-counter">%{count}</span> caràcters restants
+        password: Utilitza com a mínim 8 caràcters
         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_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.
+        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
       imports:
         data: Fitxer CSV exportat des de una altra instància de Mastodon
       sessions:
@@ -35,6 +47,18 @@ ca:
         fields:
           name: Etiqueta
           value: Contingut
+      account_warning_preset:
+        text: Text predefinit
+      admin_account_action:
+        send_email_notification: Notifica l'usuari per correu electrònic
+        text: Avís personalitzat
+        type: Acció
+        types:
+          disable: Inhabilita
+          none: No fer res
+          silence: Silenci
+          suspend: Suspèn i elimina irreversiblement les dades del compte
+        warning_preset_id: Utilitza una configuració predefinida d'avís
       defaults:
         autofollow: Convida a seguir el teu compte
         avatar: Avatar
@@ -45,11 +69,13 @@ ca:
         context: Filtre els contextos
         current_password: Contrasenya actual
         data: Informació
+        discoverable: Mostra aquest compte en el directori
         display_name: Nom visible
         email: Adreça de correu electrònic
         expires_in: Expira després
         fields: Metadades del perfil
         header: Capçalera
+        inbox_url: URL de la safata d'entrada del relay
         irreversible: Cau en lloc d'ocultar
         locale: Llengua de la interfície
         locked: Fes aquest compte privat
@@ -59,13 +85,18 @@ ca:
         otp_attempt: Codi de dos factors
         password: Contrasenya
         phrase: Paraula clau o frase
+        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'un retoot
+        setting_boost_modal: Mostra la finestra de confirmació abans d'impulsar
         setting_default_language: Llengua de les publicacions
         setting_default_privacy: Privacitat de les publicacions
         setting_default_sensitive: Marca sempre els elements multimèdia com a sensibles
         setting_delete_modal: Mostra la finestra de confirmació abans de suprimir un toot
-        setting_display_sensitive_media: Mostra sempre els elements multimèdia marcats com a sensibles
+        setting_display_media: Visualització multimèdia
+        setting_display_media_default: Per defecte
+        setting_display_media_hide_all: Amaga-ho tot
+        setting_display_media_show_all: Mostra-ho tot
+        setting_expand_spoilers: Sempre amplia els toots marcats amb advertències de contingut
         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
@@ -76,6 +107,7 @@ ca:
         type: Importa el tipus
         username: Nom d'usuari
         username_or_email: Nom d'usuari o adreça electrònica
+        whole_word: Paraula sencera
       interactions:
         must_be_follower: Blocar les notificacions de persones que no et segueixen
         must_be_following: Bloca les notificacions de persones que no segueixes
@@ -87,6 +119,7 @@ ca:
         follow_request: Envia un correu electrònic si algú sol·licita seguir-te
         mention: Envia un correu electrònic si algú et menciona
         reblog: Envia un correu electrònic si algú comparteix el teu estat
+        report: Envia un correu electrònic quan s'enviï un nou informe
     'no': 'No'
     required:
       mark: "*"
diff --git a/config/locales/simple_form.co.yml b/config/locales/simple_form.co.yml
index ac8b89a7bb151106f8f0877e9395258b2ef087d7..2fb035556934c2153d0722f559e49a9e835df9d6 100644
--- a/config/locales/simple_form.co.yml
+++ b/config/locales/simple_form.co.yml
@@ -2,56 +2,101 @@
 co:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Pudete utilizà a sintassa di i statuti, per esempiu l'URL, hashtag, minzione
+      admin_account_action:
+        send_email_notification: L'utilizatore hà da riceve una spiegazione di cio chì hè accadutu à u so contu
+        text_html: In uzzione. Pudete utilizà a sintassa di i statuti. Pudete ancu <a href="%{path}">aghjustà preselezzione d'avertimentu</a> per piglià tempu
+        type_html: Sceglie chì fà cù <strong>%{acct}</strong>
+        warning_preset_id: In uzzione. Pudete sempre aghjustà un testu persunalizatu à a fine di a preselezzione
       defaults:
-        avatar: Furmatu PNG, GIF o JPG. 2Mo o menu. Sarà ridottu à 400x400px
+        autofollow: Quelli·e chì s'arregistranu cù l'invitazione saranu autumaticamente abbunati·e à voi
+        avatar: Furmatu PNG, GIF o JPG. %{size} o menu. Sarà ridottu à %{dimensions}px
         bot: Stu contu hè autumatizatu è ùn hè forse micca survegliatu
+        context: Cuntestu·i induve u filtru deve esse applicatu
         digest: Solu mandatu dopu à una longa perioda d’inattività, è solu s’elli ci sò novi missaghji diretti
-        display_name:
-          one: Ci ferma <span class="name-counter">1</span> caratteru
-          other: Ci fermanu <span class="name-counter">%{count}</span> caratteri
+        discoverable_html: L'<a href="%{path}" target="_blank">annuariu</a> permette à a ghjente di truvà conti à partesi d'interessi è d'attività. Ci vole à avè almenu %{min_followers} abbunati
+        email: Avete da riceve un'e-mail di cunfirmazione
         fields: Pudete avè fin’à 4 elementi mustrati cum’un tavulone nant’à u vostru prufile
-        header: Furmatu PNG, GIF o JPG. 2Mo o menu. Sarà ridottu à 700x335px
+        header: Furmatu PNG, GIF o JPG. %{size} o menu. Sarà ridottu à %{dimensions}px
+        inbox_url: Cupiate l'URL di a pagina d'accolta di u ripetitore chì vulete utilizà
+        irreversible: I statuti filtrati saranu sguassati di manera irreversibile, ancu s'ellu hè toltu u filtru
+        locale: A lingua di l'interfaccia utilizatore, di l'e-mail è di e nutificazione push
         locked: Duvarete appruvà e dumande d’abbunamentu
-        note:
-          one: Ci ferma <span class="name-counter">1</span> caratteru
-          other: Ci fermanu <span class="name-counter">%{count}</span> caratteri
+        password: Ci volenu almenu 8 caratteri
+        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_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.
+        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
       imports:
         data: Un fugliale CSV da un’altr’istanza di Mastodon
       sessions:
         otp: 'Entrate u codice d’identificazione à dui fattori nant’à u vostru telefuninu, o unu di i vostri codici di ricuperazione:'
+      user:
+        chosen_languages: Soli i statuti scritti in e lingue selezziunate saranu mustrati indè e linee pubbliche
     labels:
       account:
         fields:
           name: Label
           value: Cuntinutu
+      account_warning_preset:
+        text: Testu preselezziunatu
+      admin_account_action:
+        send_email_notification: Nutificà l'utilizatore cù un'e-mail
+        text: Avertimentu persunalizatu
+        type: Azzione
+        types:
+          disable: Disattivà
+          none: Ùn fà nunda
+          silence: Silenzà
+          suspend: Suspende è sguassà i dati di u contu di manera irreversibile
+        warning_preset_id: Utilizà un'avertimentu preselezziunatu
       defaults:
+        autofollow: Invità à siguità u vostru contu
         avatar: Ritrattu di prufile
         bot: Stu contu hè un bot
+        chosen_languages: Filtrà lingue
         confirm_new_password: Cunfirmà a nova chjave d’accessu
         confirm_password: Cunfirmà a chjave d’accessu
+        context: Cuntesti di u filtru
         current_password: Chjave d’accessu attuale
         data: Dati
+        discoverable: Arregistrà stu contu indè l'annuariu
         display_name: Nome pubblicu
         email: Indirizzu e-mail
         expires_in: Spira dopu à
         fields: Metadata di u prufile
         header: Ritrattu di cuprendula
-        locale: Lingua
+        inbox_url: URL di l'inbox di u ripetitore
+        irreversible: Sguassà invece di piattà
+        locale: Lingua di l'interfaccia
         locked: Privatizà u contu
         max_uses: Numeru massimale d’utilizazione
         new_password: Nova chjave d’accessu
         note: Descrizzione
         otp_attempt: Codice d’identificazione à dui fattori
         password: Chjave d’accessu
+        phrase: Parolla-chjave o frasa
+        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
+        setting_default_language: Lingua di pubblicazione
         setting_default_privacy: Cunfidenzialità di i statuti
         setting_default_sensitive: Sempre cunsiderà media cum’è sensibili
         setting_delete_modal: Mustrà une cunfirmazione per toglie un statutu
-        setting_display_sensitive_media: Sempre mustrà media marcati cum’è sensibili
+        setting_display_media: Affissera di i media
+        setting_display_media_default: Predefinitu
+        setting_display_media_hide_all: Piattà tuttu
+        setting_display_media_show_all: Affissà tuttu
+        setting_expand_spoilers: Sempre slibrà i statutu marcati cù un'avertimentu CW
         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
@@ -62,6 +107,7 @@ co:
         type: Tippu d’impurtazione
         username: Cugnome
         username_or_email: Cugnome o Email
+        whole_word: Parolla sana
       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
@@ -73,6 +119,7 @@ co:
         follow_request: Mandà un’e-mail quandu qualch’unu vole seguitami
         mention: Mandà un’e-mail quandu qualch’unu mi mintuva
         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ò
     required:
       mark: "*"
diff --git a/config/locales/simple_form.cs.yml b/config/locales/simple_form.cs.yml
index e8e7628f360a84ac182020a4bee259d7c4599854..0e255e4dc10eb2c0850b672f8ca291a7396df67a 100644
--- a/config/locales/simple_form.cs.yml
+++ b/config/locales/simple_form.cs.yml
@@ -2,9 +2,126 @@
 cs:
   simple_form:
     hints:
+      account_warning_preset:
+        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>
+        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
       defaults:
-        avatar: PNG, GIF či JPG. Maximálně 2 MB. Bude zmenšena na 400x400px
-        bot: Tento účet provádí hlavně automatizované akce a nemusí být spravován.
-        display_name:
-          one: Zbývá <span class="name-counter">1</span> znak
-          other: Zbývá <span class="name-counter">%{count}</span> znaků
+        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
+        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ů
+        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ů
+        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.
+        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_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í.
+        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
+      imports:
+        data: Soubor CSV exportován z jiné instance Mastodon
+      sessions:
+        otp: 'Napište dvoufaktorový 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:
+      account:
+        fields:
+          name: Označení
+          value: Obsah
+      account_warning_preset:
+        text: Text přednastavení
+      admin_account_action:
+        send_email_notification: Informovat uživatele e-mailem
+        text: Vlastní varování
+        type: Akce
+        types:
+          disable: Deaktivovat
+          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í
+      defaults:
+        autofollow: Pozvat ke sledování vašeho účtu
+        avatar: Avatar
+        bot: Tohle je účet robota
+        chosen_languages: Filtrovat jazyky
+        confirm_new_password: Potvrďte nové heslo
+        confirm_password: Potvrdit heslo
+        context: Kontexty filtrů
+        current_password: Současné heslo
+        data: Data
+        discoverable: Zveřejnit tento účet v adresáři
+        display_name: Zobrazované jméno
+        email: E-mailová adresa
+        expires_in: Expirovat po
+        fields: Metadata profilu
+        header: Hlavičkový obrázek
+        inbox_url: URL schránky mostu
+        irreversible: Zahodit místo skrytí
+        locale: Jazyk rozhraní
+        locked: Zamknout účet
+        max_uses: Maximální počet použití
+        new_password: Nové heslo
+        note: O vás
+        otp_attempt: Dvoufaktorový kód
+        password: Heslo
+        phrase: Klíčové slovo či fráze
+        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
+        setting_default_language: Jazyk příspěvků
+        setting_default_privacy: Soukromí příspěvků
+        setting_default_sensitive: Vždy označovat média jako citlivá
+        setting_delete_modal: Zobrazovat před smazáním tootu potvrzovací okno
+        setting_display_media: Zobrazování médií
+        setting_display_media_default: Výchozí
+        setting_display_media_hide_all: Skrýt vše
+        setting_display_media_show_all: Zobrazit vše
+        setting_expand_spoilers: Vždy rozbalit tooty označené varováními o obsahu
+        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_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
+        severity: Přísnost
+        type: Typ importu
+        username: Uživatelské jméno
+        username_or_email: Uživatelské jméno nebo e-mail
+        whole_word: Celé slovo
+      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
+      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
+        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
+        report: Posílat e-maily, je-li odesláno nové nahlášení
+    'no': Ne
+    required:
+      mark: "*"
+      text: požadováno
+    'yes': Ano
diff --git a/config/locales/simple_form.cy.yml b/config/locales/simple_form.cy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d3f9cb340d8246294e3709c320f724f8c8ed42fa
--- /dev/null
+++ b/config/locales/simple_form.cy.yml
@@ -0,0 +1,104 @@
+---
+cy:
+  simple_form:
+    hints:
+      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
+        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
+        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_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.
+        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
+      imports:
+        data: Allforiwyd dogfen CSV o achos Mastodon arall
+      sessions:
+        otp: 'Mewnbynnwch y cod dau gam a gynhyrchwyd gan eich ap ffôn neu defnyddiwch un o''ch codau adfer:'
+      user:
+        chosen_languages: Wedi eu dewis, dim ond tŵtiau yn yr ieithoedd hyn bydd yn cael eu harddangos mewn ffrydiau cyhoeddus
+    labels:
+      account:
+        fields:
+          name: Label
+          value: Cynnwys
+      defaults:
+        autofollow: Gwahodd i ddilyn eich cyfrif
+        avatar: Afatar
+        bot: Cyfrif bot yw hwn
+        chosen_languages: Hidlo ieithoedd
+        confirm_new_password: Cadarnhau cyfrinair newydd
+        confirm_password: Cadarnhau cyfrinair
+        context: Hidlo cyd-destunau
+        current_password: Cyfrinair presennol
+        data: Data
+        display_name: Enw arddangos
+        email: Cyfeiriad e-bost
+        expires_in: Yn dod i ben ar ôl
+        fields: Metadata proffil
+        header: Pennyn
+        inbox_url: URL y mewnflwch relái
+        irreversible: Gollwng yn hytrach na chuddio
+        locale: Iaith y rhyngwyneb
+        locked: Cloi cyfrif
+        max_uses: Uchafswm y nifer o ddefnyddiau
+        new_password: Cyfrinair newydd
+        note: Bywgraffiad
+        otp_attempt: Côd dau gam
+        password: Cyfrinair
+        phrase: Allweddair neu ymadrodd
+        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
+        setting_default_privacy: Cyfrinachedd cyhoeddi
+        setting_default_sensitive: Marcio cyfryngau fel eu bod yn sensitif bob tro
+        setting_delete_modal: Dangos deialog cadarnhau cyn dileu tŵt
+        setting_display_media: Arddangos cyfryngau
+        setting_display_media_default: Rhagosodiad
+        setting_display_media_hide_all: Cuddio oll
+        setting_display_media_show_all: Dangos oll
+        setting_expand_spoilers: Ymestyn tŵtiau wedi'u marcio a rhybudd cynnwys bob tro
+        setting_hide_network: Cuddio eich rhwydwaith
+        setting_noindex: Dewis peidio mynegeio peiriant chwilota
+        setting_reduce_motion: Lleihau mudiant mewn animeiddiadau
+        setting_system_font_ui: Defnyddio ffont rhagosodedig y system
+        setting_theme: Thema'r wefan
+        setting_unfollow_modal: Dangos deialog cadarnhau cyn dad-ddilyn rhywun
+        severity: Difrifoldeb
+        type: Modd mewnforio
+        username: Enw defnyddiwr
+        username_or_email: Enw defnyddiwr neu e-bost
+        whole_word: Gair cyfan
+      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
+      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
+        reblog: Anfon e-bost pan mae rhywun yn bŵstio eich statws
+        report: Anfon e-bost pan y cyflwynir adroddiad newydd
+    'no': Na
+    required:
+      mark: "*"
+      text: gofynnol
+    'yes': Ie
diff --git a/config/locales/simple_form.da.yml b/config/locales/simple_form.da.yml
index 07862e8a82d74c20dd3e2b888a72b946bc0c65e9..f73dbac9634292170d27f50180f9c5f0eb219fe5 100644
--- a/config/locales/simple_form.da.yml
+++ b/config/locales/simple_form.da.yml
@@ -2,71 +2,84 @@
 da:
   simple_form:
     hints:
+      admin_account_action:
+        type_html: Vælg hvad du vil gøre med <strong>%{acct}</strong>
       defaults:
         autofollow: Folk der har oprettet sig gennem invitationen vil automatisk følge dig
-        avatar: PNG, GIF eller JPG. Højest 2MB. Vil blive skaleret ned til 400x400px
+        avatar: PNG, GIF eller JPG. Højest %{size}. Vil blive skaleret ned til %{dimensions}px
         bot: Denne konto udfører hovedsageligt automatiserede handlinger og bliver muligvis ikke overvåget
         context: En eller flere sammenhænge hvor filteret skal være gældende
         digest: Sendes kun efter en lang periode med inaktivitet og kun hvis du har modtaget nogle personlige beskeder mens du er væk
-        display_name:
-          one: <span class="name-counter">1</span> tegn tilbage
-          other: <span class="name-counter">%{count}</span>tegn tilbage
+        email: Du vil få tilsendt en bekræftelsed mail
         fields: Du kan have op til 4 ting vist som en tabel på din profil
-        header: PNG, GIF eller JPG. Højest 2MB. Vil blive skaleret ned til 700x335px
-        irreversible: Filtrerede toots vil forsvinde fulstændigt, selv hvis filteret senere skulle blive fjernet
+        header: PNG, GIF eller JPG. Højest %{size}. Vil blive skaleret ned til %{dimensions}px
+        inbox_url: Kopiere linket fra forsiden af den relay som du ønsker at bruge
+        irreversible: Filtrerede trut vil forsvinde fulstændigt, selv hvis filteret senere skulle blive fjernet
         locale: Sproget på interfacet, emails og push beskeder
         locked: Kræver, at du godkender følgere manuelt
-        note:
-          one: <span class="note-counter">1</span> tegn tilbage
-          other: <span class="note-counter">%{count}</span> tegn tilbage
-        phrase: Vil blive parret uanset om der er store eller små bogstaver i teksten eller om der er en advarsel om en toot
+        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 toots kan blive fundet automatisk, men det er ikke altid præcist
+        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åt du er logget ind via en hvilken som helst enhed.
+        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
       sessions:
-        otp: 'Indtast to-faktor koden der generes af appen på din fon eller brug en af din genoprettelses koder:'
+        otp: 'Indtast to-faktor koden der generes af appen af appen på din telefon eller brug en af din genoprettelses koder:'
       user:
-        chosen_languages: Når markeret, vil kun toots i de valgte sprog blive vist på offentlige tidslinjer
+        chosen_languages: Når markeret, vil kun trut i de valgte sprog blive vist på offentlige tidslinjer
     labels:
       account:
         fields:
           name: Etiket
           value: Indhold
+      admin_account_action:
+        type: Handling
+        types:
+          disable: Deaktiver
+          none: Gør intet
       defaults:
         autofollow: Inviter til at følge din konto
         avatar: Profilbillede
-        bot: Dette er en bot konto
+        bot: Dette er en robot konto
         chosen_languages: Filtrer sprog
-        confirm_new_password: Bekræft dit nye kodeord
-        confirm_password: Bekræft kodeord
+        confirm_new_password: Bekræft din nye adgangskode
+        confirm_password: Bekræft adgangskode
         context: Filtrer sammenhænge
-        current_password: Nuværende kodeord
+        current_password: Nuværende adgangskode
         data: Data
         display_name: Visningsnavn
         email: E-mail adresse
         expires_in: Udløber efter
         fields: Profil metadata
         header: Overskrift
+        inbox_url: Link til relay indbakken
         irreversible: Ignorer istedet for at skjule
         locale: Sprog på interface
         locked: LÃ¥s konto
         max_uses: Højeste antal benyttelser
-        new_password: Nyt kodeord
+        new_password: Ny adgangskode
         note: Biografi
         otp_attempt: To-faktor kode
-        password: Kodeord
+        password: Adgangskode
         phrase: Nøgleord eller sætning
         setting_auto_play_gif: Afspil automatisk animerede GIFs
         setting_boost_modal: Vis bekræftelses dialog før du fremhæver
         setting_default_language: Sprog for opslag
         setting_default_privacy: Privatliv
-        setting_default_sensitive: Marker altid multimedia som værende følsomt
-        setting_delete_modal: Vis bekræftelses dialog før du sletter et toot
-        setting_display_sensitive_media: Vis altid multimedier markeret som værende følsomt
+        setting_default_sensitive: Marker altid medier som værende følsomt
+        setting_delete_modal: Vis bekræftelses dialog før du sletter et trut
+        setting_display_media: Visning af medier
+        setting_display_media_default: Standard
+        setting_display_media_hide_all: Skjul alle
+        setting_display_media_show_all: Vis alle
+        setting_expand_spoilers: Udvid altid trut der er markeret med indholdsadvarsler
         setting_hide_network: Skjul dit netværk
         setting_noindex: Frameld dig søgemaskiners indeksering
         setting_reduce_motion: Reducer animationers bevægelse
@@ -77,6 +90,7 @@ da:
         type: Importtype
         username: Brugernavn
         username_or_email: Brugernavn eller Email
+        whole_word: Helt ord
       interactions:
         must_be_follower: Bloker notifikationer fra folk der ikke følger dig
         must_be_following: Bloker notifikationer fra folk du ikke følger
@@ -88,6 +102,7 @@ da:
         follow_request: Send email når nogen anmoder om at følge dig
         mention: Send e-mail når nogen nævner dig
         reblog: Send email når nogen fremhæver din status
+        report: Send email når en ny anmeldelse bliver indsendt
     'no': Nej
     required:
       mark: "*"
diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml
index fb8d9e7c7583f1e5e2f4f0d75dea28db7b67c25a..3958e315f665ee661f8d6f88c2bcf5959792be89 100644
--- a/config/locales/simple_form.de.yml
+++ b/config/locales/simple_form.de.yml
@@ -2,29 +2,40 @@
 de:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Du kannst Toot-Syntax benutzen, wie zum Beispiel 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
+        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 2 MB. Wird auf 400×400 px herunterskaliert
+        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
-        display_name:
-          one: <span class="name-counter">1</span> Zeichen verbleibt
-          other: <span class="name-counter">%{count}</span> Zeichen verbleiben
-        fields: Du kannst bis zu 4 Elemente als Tabelle dargestellt auf deinem Profil anzeigen lassen
-        header: PNG, GIF oder JPG. Maximal 2 MB. Wird auf 700×335 px herunterskaliert
+        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
+        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
         locale: Die Sprache der Oberfläche, E-Mails und Push-Benachrichtigungen
         locked: Wer dir folgen möchte, muss um deine Erlaubnis bitten
-        note:
-          one: <span class="note-counter">1</span> Zeichen verbleibt
-          other: <span class="note-counter">%{count}</span> Zeichen verbleiben
+        password: Verwende mindestens 8 Zeichen
         phrase: Wird unabhängig vom umgebenen Text oder 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_hide_network: Wem du folgst und wer dir folgt wird in deinem Profil nicht angezeigt
+        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
       imports:
         data: CSV-Datei, die aus einer anderen Mastodon-Instanz exportiert wurde
       sessions:
@@ -36,22 +47,36 @@ de:
         fields:
           name: Bezeichnung
           value: Inhalt
+      account_warning_preset:
+        text: Vorlagentext
+      admin_account_action:
+        send_email_notification: Benachrichtige den Nutzer per E-Mail
+        text: Eigene Warnung
+        type: Aktion
+        types:
+          disable: Deaktivieren
+          none: Nichts tun
+          silence: Stummschalten
+          suspend: Deaktivieren und unwiderruflich Benutzerdaten löschen
+        warning_preset_id: Benutze eine Warnungsvorlage
       defaults:
-        autofollow: Einladen, um deinen Account zu folgen
+        autofollow: Einladen, um deinem Account zu folgen
         avatar: Profilbild
-        bot: Dies ist ein bot Benutzer
+        bot: Dieser Benutzer ist ein Bot
         chosen_languages: Sprachen filtern
         confirm_new_password: Neues Passwort bestätigen
         confirm_password: Passwort bestätigen
         context: Aspekte filtern
         current_password: Derzeitiges Passwort
         data: Daten
+        discoverable: Dieses Benutzerkonto im Verzeichnis auflisten
         display_name: Anzeigename
         email: E-Mail-Adresse
-        expires_in: Gültig bis
+        expires_in: Läuft ab
         fields: Profil-Metadaten
         header: Kopfbild
-        irreversible: Fallen lassen anstatt es zu verstecken
+        inbox_url: Inbox-URL des Relays
+        irreversible: Verwerfen statt verstecken
         locale: Sprache der Benutzeroberfläche
         locked: Gesperrtes Profil
         max_uses: Maximale Verwendungen
@@ -60,27 +85,33 @@ de:
         otp_attempt: Zwei-Faktor-Authentisierungs-Code
         password: Passwort
         phrase: Schlagwort oder Phrase
+        setting_aggregate_reblogs: Gruppiere erneut geteilte Beiträge in Zeitleisten
         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 heikel markieren
+        setting_default_sensitive: Medien immer als sensibel markieren
         setting_delete_modal: Bestätigungsdialog anzeigen, bevor ein Beitrag gelöscht wird
-        setting_display_sensitive_media: Medien, die als heikel markiert sind, immer anzeigen
+        setting_display_media: Medien-Anzeige
+        setting_display_media_default: Standard
+        setting_display_media_hide_all: Alle verstecken
+        setting_display_media_show_all: Alle anzeigen
+        setting_expand_spoilers: Beiträge mit Inhaltswarnungen immer ausklappen
         setting_hide_network: Blende dein Netzwerk aus
         setting_noindex: Suchmaschinen-Indexierung verhindern
         setting_reduce_motion: Bewegung in Animationen verringern
         setting_system_font_ui: Standardschriftart des Systems verwenden
         setting_theme: Theme der Website
-        setting_unfollow_modal: Bestätigungsdialog anzeigen, bevor jemand entfolgt wird
+        setting_unfollow_modal: Bestätigungsdialog anzeigen, bevor jemandem entfolgt wird
         severity: Schweregrad
         type: Importtyp
         username: Profilname
-        username_or_email: Profilname oder Email
+        username_or_email: Profilname oder E-Mail
+        whole_word: Ganzes Wort
       interactions:
         must_be_follower: Benachrichtigungen von Nicht-Folgenden blockieren
         must_be_following: Benachrichtigungen von Profilen blockieren, denen ich nicht folge
-        must_be_following_dm: Private Nachrichten von Profilen denen ich nicht folge blockieren
+        must_be_following_dm: Private Nachrichten von Profilen, denen ich nicht folge, blockieren
       notification_emails:
         digest: Schicke Übersichts-E-Mails
         favourite: E-Mail senden, wenn jemand meinen Beitrag favorisiert
@@ -88,6 +119,7 @@ de:
         follow_request: E-Mail senden, wenn mir jemand folgen möchte
         mention: E-Mail senden, wenn mich jemand erwähnt
         reblog: E-Mail senden, wenn jemand meinen Beitrag teilt
+        report: E-Mail senden, wenn ein neuer Bericht vorliegt
     'no': Nein
     required:
       mark: "*"
diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml
index 00fba5d27d1aa4cd6277be2a7810a5ebe04be203..fecddd11f5a4a26f00822607fdf0864b1bbbaa70 100644
--- a/config/locales/simple_form.el.yml
+++ b/config/locales/simple_form.el.yml
@@ -2,29 +2,40 @@
 el:
   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: PNG, GIF ή JPG. Έως 2MB. Θα μειωθεί σε διάσταση 400x400px
+        avatar: PNG, GIF ή JPG. Έως %{size}. Θα περιοριστεί σε διάσταση %{dimensions}px
         bot: Ο λογαριασμός αυτός εκτελεί κυρίως αυτοματοποιημένες ενέργειες και ίσως να μην παρακολουθείται
         context: Ένα ή περισσότερα πλαίσια στα οποία μπορεί να εφαρμόζεται αυτό το φίλτρο
         digest: Αποστέλλεται μόνο μετά από μακρά περίοδο αδράνειας και μόνο αν έχεις λάβει προσωπικά μηνύματα κατά την απουσία σου
-        display_name:
-          one: απομένει <span class="name-counter">1</span> χαρακτήρας
-          other: απομένουν <span class="name-counter">%{count}</span> χαρακτήρες
+        discoverable_html: "Ο <a href=\"%{path}\" target=\"_blank\">κατάλογος</a> \nσου επιτρέπει να βρεις λογαριασμούς βάσει ενδιαφερόντων και δραστηριότητας. Απαιτεί τουλάχιστον %{min_followers} ακόλουθους"
+        email: Θα σου σταλεί email επιβεβαίωσης
         fields: Μπορείς να έχεις έως 4 σημειώσεις σε μορφή πίνακα στο προφίλ σου
-        header: PNG, GIF ή JPG. Έως 2MB. Θα μειωθεί σε διάσταση 700x335px
+        header: PNG, GIF ή JPG. Έως %{size}. Θα περιοριστεί σε διάσταση %{dimensions}px
+        inbox_url: Αντέγραψε το URL της αρχικής σελίδας του ανταποκριτή (relay) που θέλεις να χρησιμοποιήσεις
         irreversible: Τα φιλτραρισμένα τουτ θα εξαφανιστούν αμετάκλητα, ακόμα και αν το φίλτρο αργότερα αφαιρεθεί
         locale: Η γλώσσα του περιβάλλοντος χρήσης, των email και των ειδοποιήσεων ώθησης
         locked: Απαιτεί να εγκρίνεις χειροκίνητα τους ακόλουθούς σου
-        note:
-          one: απομένει <span class="note-counter">1</span> χαρακτήρας
-          other: απομένουν <span class="note-counter">%{count}</span> χαρακτήρες
+        password: Χρησιμοποίησε τουλάχιστον 8 χαρακτήρες
         phrase: Θα ταιριάζει ανεξαρτήτως πεζών/κεφαλαίων ή προειδοποίησης περιεχομένου του τουτ
         scopes: Ποια API θα επιτρέπεται στην εφαρμογή να χρησιμοποιήσεις. Αν επιλέξεις κάποιο υψηλό εύρος εφαρμογής, δε χρειάζεται να επιλέξεις και εξειδικευμένα.
+        setting_aggregate_reblogs: Απόκρυψη των νέων προωθήσεωνγια τα τουτ που έχουν προωθηθεί πρόσφατα (επηρεάζει μόνο τις νέες προωθήσεις)
         setting_default_language: Η γλώσσα των τουτ σου μπορεί να ανιχνευτεί αυτόματα αλλά δεν είναι πάντα ακριβές
-        setting_hide_network: Το ποιους ακολουθείς και το ποιοι σε ακολουθούν δε θα φαίνεται στο προφίλ σου
+        setting_display_media_default: Απόκρυψη ευαίσθητων πολυμέσων
+        setting_display_media_hide_all: Μόνιμη απόκρυψη όλων των πολυμέσων
+        setting_display_media_show_all: Μόνιμη εμφάνιση ευαίσθητων πολυμέσων
+        setting_hide_network: Δε θα εμφανίζεται στο προφίλ σου ποιους ακολουθείς και ποιοι σε ακολουθούν
         setting_noindex: Επηρεάζει το δημόσιο προφίλ και τις δημοσιεύσεις σου
         setting_theme: Επηρεάζει την εμφάνιση του Mastodon όταν συνδέεται από οποιαδήποτε συσκευή.
+        username: Το όνομα χρήστη σου θα είναι μοναδικό στο %{domain}
+        whole_word: Όταν η λέξη ή η φράση κλειδί είναι μόνο αλφαριθμητική, θα εφαρμοστεί μόνο αν ταιριάζει με ολόκληρη τη λέξη
       imports:
         data: Αρχείο CSV που έχει εξαχθεί από διαφορετικό κόμβο Mastodon
       sessions:
@@ -36,6 +47,18 @@ el:
         fields:
           name: Ταμπέλα
           value: Περιεχόμενο
+      account_warning_preset:
+        text: Προκαθορισμένο κείμενο
+      admin_account_action:
+        send_email_notification: Ενημέρωση χρήστη μέσω email
+        text: Προσαρμοσμένη προειδοποίηση
+        type: Ενέργεια
+        types:
+          disable: Απενεργοποίηση
+          none: Καμία ενέργεια
+          silence: Αποσιώπηση
+          suspend: Αναστολή και αμετάκλητη διαγραφή στοιχείων λογαριασμού
+        warning_preset_id: Χρήση προκαθορισμένης προειδοποίησης
       defaults:
         autofollow: Προσκάλεσε για να ακολουθήσουν το λογαριασμό σου
         avatar: Αβατάρ
@@ -46,11 +69,13 @@ el:
         context: Πλαίσια φιλτραρίσματος
         current_password: Τρέχον συνθηματικό
         data: Δεδομένα
+        discoverable: Εμφάνιση αυτού του λογαριασμού στον κατάλογο
         display_name: Όνομα εμφάνισης
         email: Διεύθυνση email
         expires_in: Λήξη μετά από
         fields: Μετεδεδομένα προφίλ
         header: Επικεφαλίδα
+        inbox_url: Το URL του inbox του ανταποκριτή (relay)
         irreversible: Απόρριψη αντί για κρύψιμο
         locale: Γλώσσα περιβάλλοντος
         locked: Κλείδωμα λογαριασμού
@@ -60,13 +85,18 @@ el:
         otp_attempt: Κωδικός δυο παραγόντων
         password: Συνθηματικό
         phrase: Λέξη ή φράση κλειδί
+        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_sensitive_media: Εμφάνιση πάντα των πολυμέσων σημειωμένων ως ευαίσθητων
+        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: Μείωση κίνησης κινουμένων στοιχείων
@@ -77,6 +107,7 @@ el:
         type: Τύπος εισαγωγής
         username: Όνομα χρηστη
         username_or_email: Όνομα ή διεύθυνση email χρήστη
+        whole_word: Ολόκληρη λέξη
       interactions:
         must_be_follower: Μπλόκαρε τις ειδοποιήσεις από όσους δεν ακολουθείς
         must_be_following: Μπλόκαρε τις ειδοποιήσεις που προέρχονται από άτομα που δεν τα ακολουθείς
@@ -88,6 +119,7 @@ el:
         follow_request: Στέλνε email όταν κάποιος ζητάει να σε ακολουθήσει
         mention: Στέλνε email όταν κάποιος σε αναφέρει
         reblog: Στέλνε email όταν κάποιος προωθεί τη δημοσίευση σου
+        report: Αποστολή email όταν υποβάλλεται νέα καταγγελία
     'no': Όχι
     required:
       mark: "*"
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 49d94bcde9e1d0cafd416021169043ac8d3e6fbf..4363c59e429c8ab4706deca90ac38c8818a5cbb7 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -2,29 +2,40 @@
 en:
   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 2MB. Will be downscaled to 400x400px
+        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
-        display_name:
-          one: <span class="name-counter">1</span> character left
-          other: <span class="name-counter">%{count}</span> characters left
+        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 2MB. Will be downscaled to 700x335px
+        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
-        note:
-          one: <span class="note-counter">1</span> character left
-          other: <span class="note-counter">%{count}</span> characters left
+        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_default_language: The language of your toots can be detected automatically, but it's not always accurate
+        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.
+        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
       imports:
         data: CSV file exported from another Mastodon instance
       sessions:
@@ -36,6 +47,18 @@ en:
         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
@@ -46,11 +69,13 @@ en:
         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
@@ -60,13 +85,18 @@ en:
         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_sensitive_media: Always show media marked as sensitive
+        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
@@ -77,6 +107,7 @@ en:
         type: Import type
         username: Username
         username_or_email: Username or Email
+        whole_word: Whole word
       interactions:
         must_be_follower: Block notifications from non-followers
         must_be_following: Block notifications from people you don't follow
@@ -88,6 +119,7 @@ en:
         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: "*"
diff --git a/config/locales/simple_form.en_GB.yml b/config/locales/simple_form.en_GB.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d9e1a256f6c9a5842d1647e5207699a27c1afc83
--- /dev/null
+++ b/config/locales/simple_form.en_GB.yml
@@ -0,0 +1,2 @@
+---
+{}
diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml
index a46fcc42e6391bce8369349ee236b8de1bc66564..b78d2dd81399afe956c2d88ca6e76b91ba75c4aa 100644
--- a/config/locales/simple_form.eo.yml
+++ b/config/locales/simple_form.eo.yml
@@ -4,26 +4,28 @@ eo:
     hints:
       defaults:
         autofollow: Homoj, kiuj registriĝos per la invito aŭtomate sekvos vin
-        avatar: Formato PNG, GIF aÅ­ JPG. Äœis 2MB. Estos malgrandigita al 400x400px
+        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
-        display_name:
-          one: <span class="name-counter">1</span> signo restas
-          other: <span class="name-counter">%{count}</span> signoj restas
+        email: Vi ricevos konfirman retmesaĝon
         fields: Vi povas havi ĝis 4 tabelajn elementojn en via profilo
-        header: Formato PNG, GIF aÅ­ JPG. Äœis 2MB. Estos malgrandigita al 700x335px
+        header: Formato PNG, GIF aÅ­ JPG. Äœis %{size}. Estos malgrandigita al %{dimensions}px
+        inbox_url: Kopiu la URL de la ĉefpaĝo de la ripetilo, kiun vi volas uzi
         irreversible: Elfiltritaj mesaĝoj malaperos por ĉiam, eĉ se la filtrilo estas poste forigita
         locale: La lingvo de la uzant-interfaco, retmesaĝoj kaj puŝ-sciigoj
         locked: Vi devos aprobi ĉiun peton de sekvado mane
-        note:
-          one: <span class="note-counter">1</span> signo restas
-          other: <span class="note-counter">%{count}</span> signoj restas
+        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
+        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.
+        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
       imports:
         data: CSV-dosiero el alia nodo de Mastodon
       sessions:
@@ -50,6 +52,7 @@ eo:
         expires_in: Eksvalidiĝas post
         fields: Profilaj metadatumoj
         header: Fonbildo
+        inbox_url: URL de la ripetila enirkesto
         irreversible: Forĵeti anstataŭ kaŝi
         locale: Interfaca lingvo
         locked: Åœlosi konton
@@ -65,7 +68,11 @@ eo:
         setting_default_privacy: Mesaĝa videbleco
         setting_default_sensitive: Ĉiam marki aŭdovidaĵojn tiklaj
         setting_delete_modal: Montri fenestron por konfirmi antaŭ ol forigi mesaĝon
-        setting_display_sensitive_media: Ĉiam montri aŭdovidaĵojn markitajn tiklaj
+        setting_display_media: Aŭdovidaĵa montrado
+        setting_display_media_default: Dekomenca
+        setting_display_media_hide_all: Kaŝi ĉiujn
+        setting_display_media_show_all: Montri ĉiujn
+        setting_expand_spoilers: Ĉiam grandigi mesaĝojn markitajn per avertoj pri enhavo
         setting_hide_network: Kaŝi viajn sekvantojn kaj sekvatojn
         setting_noindex: Ellistiĝi de retserĉila indeksado
         setting_reduce_motion: Malrapidigi animaciojn
@@ -76,6 +83,7 @@ eo:
         type: Importa tipo
         username: Uzantnomo
         username_or_email: Uzantnomo aÅ­ Retadreso
+        whole_word: Tuta vorto
       interactions:
         must_be_follower: Bloki sciigojn de nesekvantoj
         must_be_following: Bloki sciigojn de homoj, kiujn vi ne sekvas
@@ -87,6 +95,7 @@ eo:
         follow_request: Sendi retmesaĝon kiam iu petas sekvi vin
         mention: Sendi retmesaĝon kiam iu mencias vin
         reblog: Sendi retmesaĝon kiam iu diskonigas vian mesaĝon
+        report: Sendi retmesaĝon kiam nova signalo estas sendita
     'no': Ne
     required:
       mark: "*"
diff --git a/config/locales/simple_form.es.yml b/config/locales/simple_form.es.yml
index 000a33edc62467fb0e263bd35ca09bd9601e7dbc..c0d72dc2782acb3c870f4c918f3c4be93f0e2efd 100644
--- a/config/locales/simple_form.es.yml
+++ b/config/locales/simple_form.es.yml
@@ -3,33 +3,52 @@ es:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF o JPG. Máximo 2MB. Será escalado a 400x400px
+        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
-        display_name:
-          one: <span class="name-counter">1</span> caracter restante
-          other: <span class="name-counter">%{count}</span> caracteres restantes
-        header: PNG, GIF o JPG. Máximo 2MB. Será escalado a 700x335px
+        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
-        note:
-          one: <span class="name-counter">1</span> carácter restante
-          other: <span class="name-counter">%{count}</span> caracteres restantes
+        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.
+        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
       sessions:
-        otp: Introduce el código de autenticación de dos factores de tu teléfono o usa uno de tus códigos de recuperación.
+        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:
+        chosen_languages: Cuando se marca, solo se mostrarán los toots en los idiomas seleccionados en los timelines públicos
     labels:
+      account:
+        fields:
+          name: Etiqueta
+          value: Contenido
       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
         confirm_password: Confirmar contraseña
+        context: Filtrar contextos
         current_password: Contraseña actual
         data: Información
         display_name: Nombre para mostrar
         email: Dirección de correo electrónico
         expires_in: Expirar tras
+        fields: Metadatos de perfil
         header: Img. cabecera
+        inbox_url: URL de la entrada de relés
+        irreversible: Dejar en lugar de ocultar
         locale: Idioma
         locked: Hacer privada esta cuenta
         max_uses: Máx. número de usos
@@ -37,12 +56,14 @@ es:
         note: Biografía
         otp_attempt: Código de dos factores
         password: Contraseña
+        phrase: Palabra clave o frase
         setting_auto_play_gif: Reproducir automáticamente los GIFs animados
         setting_boost_modal: Mostrar ventana de confirmación antes de un Retoot
+        setting_default_language: Idioma de publicación
         setting_default_privacy: Privacidad de publicaciones
         setting_default_sensitive: Marcar siempre imágenes como sensibles
         setting_delete_modal: Mostrar diálogo de confirmación antes de borrar un toot
-        setting_display_sensitive_media: Mostrar siempre material marcado como sensible
+        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_system_font_ui: Utilizar la tipografía por defecto del sistema
@@ -52,6 +73,7 @@ es:
         type: Importar tipo
         username: Nombre de usuario
         username_or_email: Usuario o Email
+        whole_word: Toda la palabra
       interactions:
         must_be_follower: Bloquear notificaciones de personas que no te siguen
         must_be_following: Bloquear notificaciones de personas que no sigues
@@ -63,6 +85,7 @@ es:
         follow_request: Enviar correo electrónico cuando alguien solicita seguirte
         mention: Enviar correo electrónico cuando alguien te mencione
         reblog: Enviar correo electrónico cuando alguien comparta su publicación
+        report: Enviar un correo cuando se envía un nuevo informe
     'no': 'No'
     required:
       mark: "*"
diff --git a/config/locales/simple_form.eu.yml b/config/locales/simple_form.eu.yml
index 2d60030ec19ed0e50ef435812fc31a0aacde9d85..0ffc22b53d158dad6ae7012bcc79a294ecaf0ff6 100644
--- a/config/locales/simple_form.eu.yml
+++ b/config/locales/simple_form.eu.yml
@@ -2,25 +2,40 @@
 eu:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Toot sintaxia erabili dezakezu, URLak, traolak eta aipamenak
+      admin_account_action:
+        send_email_notification: Erabiltzaileak bere kontuarekin gertatutakoaren azalpen bat jasoko du
+        text_html: Aukerakoa. Toot sintaxia erabili dezakezu. <a href="%{path}">Abisu aurre-ezarpenak</a> gehitu ditzakezu denbora aurrezteko
+        type_html: Erabaki zer egin <strong>%{acct}</strong> kontuarekin
+        warning_preset_id: Aukerakoa. Zure testua gehitu dezakezu aurre-ezarpenaren ostean
       defaults:
-        autofollow: Gonbidapena erabiliz izena ematen dutenek automatikoki jarraituko zaituzte
-        avatar: PNG, GIF edo JPG. Gehienez 2MB. 400x400px neurrira eskalatuko da
+        autofollow: Gonbidapena erabiliz izena ematen dutenek automatikoki jarraituko dizute
+        avatar: PNG, GIF edo JPG. Gehienez %{size}. %{dimensions}px neurrira eskalatuko da
         bot: Kontu honek nagusiki automatizatutako ekintzak burutzen ditu eta agian ez du inork monitorizatzen
+        context: Iragazkia aplikatzeko testuinguru bat edo batzuk
         digest: Soilik jarduerarik gabeko epe luze bat eta gero, eta soilik ez zeudela mezu pertsonalen bat jaso baduzu
-        display_name:
-          one: Karaktere <span class="name-counter">1</span> geratzen da
-          other: <span class="name-counter">%{count}</span> karaktere geratzen dira
+        discoverable_html: <a href="%{path}" target="_blank">Direktorioa</a>k Jendea interesen eta jardueraren arabera aurkitzea ahalbidetzen du. Gutxienez %{min_followers} jarraitzaile behar dira bertan agertzeko
+        email: Baieztapen e-mail bat bidaliko zaizu
         fields: 4 elementu bistaratu ditzakezu taula batean zure profilean
-        header: PNG, GIF edo JPG. Gehienez 2MB. 700x335px eskalara txikituko da
+        header: PNG, GIF edo JPG. Gehienez %{size}. %{dimensions}px eskalara txikituko da
+        inbox_url: Kopiatu erabili nahi duzun errelearen hasiera orriaren URLa
+        irreversible: Iragazitako Toot-ak betirako galduko dira, geroago iragazkia kentzen baduzu ere
         locale: Erabiltzaile-interfazea, e-mail mezuen eta jakinarazpenen hizkuntza
         locked: Jarraitzaileak eskuz onartu behar dituzu
-        note:
-          one: Karaktere<span class="note-counter">1</span> geratzen da
-          other: <span class="note-counter"> %{count}</span> karaktere geratzen dira
-        setting_default_language: Zure toot-en hizkuntza automatikoki antzeman daiteke, baina ez da beti zehatza
+        password: Erabili 8 karaktere gutxienez
+        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_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 orrietan eragina du
+        setting_noindex: Zure profil publiko eta Toot-en orrietan eragina du
         setting_theme: Edozein gailutik konektatzean Mastodon-en itxuran eragiten du.
+        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
       imports:
         data: Beste Mastodon instantzia batetik esportatutako CSV fitxategia
       sessions:
@@ -32,6 +47,17 @@ eu:
         fields:
           name: Etiketa
           value: Edukia
+      account_warning_preset:
+        text: Aurrez ezarritako testua
+      admin_account_action:
+        send_email_notification: Jakinarazi erabiltzaileari e-mail bidez
+        text: Abisu pertsonalizatua
+        type: Ekintza
+        types:
+          disable: Desaktibatu
+          none: Ez egin ezer
+          silence: Isiltarazi
+        warning_preset_id: Erabili aurre-ezarritako abisu bat
       defaults:
         autofollow: Gonbidatu zure kontua jarraitzera
         avatar: Abatarra
@@ -39,13 +65,17 @@ eu:
         chosen_languages: Iragazi hizkuntzak
         confirm_new_password: Berretsi pasahitz berria
         confirm_password: Berretsi pasahitza
+        context: Iragazkiaren testuinguruak
         current_password: Oraingo pasahitza
         data: Datuak
+        discoverable: Zerrendatu kontu hau direktorioan
         display_name: Pantaila-izena
         email: E-mail helbidea
         expires_in: Iraungitzea
         fields: Profilaren metadatuak
         header: Goiburua
+        inbox_url: Errelearen sarrera ontziaren URLa
+        irreversible: Baztertu ezkutatu ordez
         locale: Interfazearen hizkuntza
         locked: Giltzapetu kontua
         max_uses: Gehieneko erabiltzaile kopurua
@@ -53,13 +83,19 @@ eu:
         note: Biografia
         otp_attempt: Bi faktoreetako kodea
         password: Pasahitza
+        phrase: Hitz edo esaldi gakoa
+        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
         setting_default_language: Argitalpenen hizkuntza
         setting_default_privacy: Mezuen pribatutasuna
         setting_default_sensitive: Beti markatu edukiak hunkigarri gisa
         setting_delete_modal: Erakutsi baieztapen elkarrizketa-koadroa toot bat ezabatu aurretik
-        setting_display_sensitive_media: Beti erakutsi hunkigarri gisa markatutako edukia
+        setting_display_media: Multimedia bistaratzea
+        setting_display_media_default: Lehenetsia
+        setting_display_media_hide_all: Ezkutatu guztia
+        setting_display_media_show_all: Erakutsi guztia
+        setting_expand_spoilers: Hedatu beti edukia abisua (CW) duten  tootak
         setting_hide_network: Ezkutatu zure sarea
         setting_noindex: Atera bilaketa motorraren indexaziotik
         setting_reduce_motion: Murriztu animazioen mugimenduak
@@ -70,6 +106,7 @@ eu:
         type: Inportazio mota
         username: Erabiltzaile-izena
         username_or_email: Erabiltzaile-izena edo e-mail helbidea
+        whole_word: Hitz osoa
       interactions:
         must_be_follower: Blokeatu jarraitzaile ez direnen jakinarazpenak
         must_be_following: Blokeatu zuk jarraitzen ez dituzunen jakinarazpenak
@@ -81,6 +118,7 @@ eu:
         follow_request: Bidali e-mail bat norbaitek zu jarraitzea eskatzen duenean
         mention: Bidali e-mail bat norbaitek zu aipatzean
         reblog: Bidali e-mail bat norbaitek zure mezuari bultzada ematen badio
+        report: Bidali e-maila txosten berri bat aurkezten denean
     'no': Ez
     required:
       mark: "*"
diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml
index 2a2cc6731a05f0538f5875fd192101ad11cb7864..2eeacade62761337197bf331869e75c96b668c6a 100644
--- a/config/locales/simple_form.fa.yml
+++ b/config/locales/simple_form.fa.yml
@@ -4,26 +4,29 @@ fa:
     hints:
       defaults:
         autofollow: کسانی که از راه دعوت‌نامه عضو می‌شوند به طور خودکار پیگیر شما خواهند شد
-        avatar: یکی از قالب‌های PNG یا  GIF یا JPG. بیشترین اندازه ۲ مگابایت. تصویر به اندازهٔ ۴۰۰×۴۰۰ پیکسل تبدیل خواهد شد
+        avatar: یکی از قالب‌های PNG یا  GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد
         bot: این حساب بیشتر به طور خودکار فعالیت می‌کند و نظارت پیوسته‌ای روی آن وجود ندارد
         context: یک یا چند زمینه که فیلتر باید در آن‌ها اعمال شود
         digest: تنها وقتی فرستاده می‌شود که مدتی طولانی فعالیتی نداشته باشید و در این مدت برای شما پیغام خصوصی‌ای نوشته شده باشد
-        display_name:
-          one: <span class="name-counter">1</span> حرف باقی مانده
-          other: <span class="name-counter">%{count}</span> حرف باقی مانده
+        email: به شما ایمیل تأییدی فرستاده خواهد شد
         fields: شما می‌توانید تا چهار مورد را در یک جدول در نمایهٔ خود نمایش دهید
-        header: یکی از قالب‌های PNG یا  GIF یا JPG. بیشترین اندازه ۲ مگابایت. تصویر به اندازهٔ ۳۳۵×۷۰۰ پیکسل تبدیل خواهد شد
+        header: یکی از قالب‌های PNG یا  GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد
+        inbox_url: نشانی صفحهٔ اصلی رله‌ای را که می‌خواهید به کار ببرید کپی کنید
         irreversible: بوق‌های فیلترشده به طور برگشت‌ناپذیری ناپدید می‌شوند، حتی اگر فیلتر را بعداً بردارید
         locale: زبان محیط کاربری، ایمیل‌ها، و اعلان‌ها
         locked: باید پیگیران تازه را خودتان تأیید کنید
-        note:
-          one: <span class="note-counter">1</span> حرف باقی مانده
-          other: <span class="note-counter">%{count}</span> حرف باقی مانده
+        password: دست‌کم باید ۸ نویسه داشته باشد
         phrase: مستقل از کوچکی و بزرگی حروف، با متن اصلی یا هشدار محتوای بوق‌ها مقایسه می‌شود
-        setting_default_language: زبان نوشته‌های شما به طور خودکار تشخیص داده می‌شود، ولی این تشخصی همیشه دقیق نیست
+        scopes: واسط‌های برنامه‌نویسی که این برنامه به آن دسترسی دارد. اگر بالاترین سطح دسترسی را انتخاب کنید، دیگر نیازی به انتخاب سطح‌های پایینی ندارید.
+        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:
         data: پروندهٔ CSV که از سرور ماستدون دیگری برون‌سپاری شده
       sessions:
@@ -50,6 +53,7 @@ fa:
         expires_in: تاریخ انقضا
         fields: اطلاعات تکمیلی نمایه
         header: تصویر زمینه
+        inbox_url: نشانی صندوق ورودی رله
         irreversible: به جای پنهان‌سازی، حذف کن
         locale: زبان محیط کاربری
         locked: خصوصی‌کردن حساب
@@ -65,7 +69,11 @@ fa:
         setting_default_privacy: حریم خصوصی نوشته‌ها
         setting_default_sensitive: همیشه تصاویر را به عنوان حساس علامت بزن
         setting_delete_modal: نمایش پیغام تأیید پیش از پاک کردن یک نوشته
-        setting_display_sensitive_media: همیشه تصویرهای علامت‌زده‌شده به عنوان حساس را نمایش بده
+        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: کاستن از حرکت در پویانمایی‌ها
@@ -74,8 +82,9 @@ fa:
         setting_unfollow_modal: نمایش پیغام تأیید پیش از لغو پیگیری دیگران
         severity: شدت
         type: نوع درون‌ریزی
-        username: نام کاربری (تنها حروف انگلیسی)
+        username: نام کاربری (لاتین)
         username_or_email: نام کاربری یا ایمیل
+        whole_word: تطابق واژهٔ کامل
       interactions:
         must_be_follower: مسدودکردن اعلان‌های همه به جز پیگیران
         must_be_following: مسدودکردن اعلان‌های کسانی که شما پی نمی‌گیرید
@@ -87,6 +96,7 @@ fa:
         follow_request: وقتی کسی درخواست پیگیری کرد ایمیل بفرست
         mention: وقتی کسی از شما نام برد ایمیل بفرست
         reblog: وقتی کسی نوشتهٔ شما را بازبوقید ایمیل بفرست
+        report: وقتی گزارش تازه‌ای فرستاده شد ایمیل بفرست
     'no': خیر
     required:
       mark: "*"
diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml
index 190790ca55814468586d1153f6a5e072182aef50..b0f958f2f17323b5b531546bb67f36d7458467a3 100644
--- a/config/locales/simple_form.fi.yml
+++ b/config/locales/simple_form.fi.yml
@@ -3,17 +3,11 @@ fi:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF tai JPG. Enintään 2 Mt. Skaalataan kokoon 400 x 400 px
+        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
-        display_name:
-          one: <span class="name-counter">1</span> merkki jäljellä
-          other: <span class="name-counter">%{count}</span> merkkiä jäljellä
         fields: Sinulla voi olla korkeintaan 4 asiaa profiilissasi taulukossa
-        header: PNG, GIF tai JPG. Enintään 2 Mt. Skaalataan kokoon 700 x 335 px
+        header: PNG, GIF tai JPG. Enintään %{size}. Skaalataan kokoon %{dimensions} px
         locked: Sinun täytyy hyväksyä seuraajat manuaalisesti
-        note:
-          one: <span class="note-counter">1</span> merkki jäljellä
-          other: <span class="note-counter">%{count}</span> merkkiä jäljellä
         setting_noindex: Vaikuttaa julkiseen profiiliisi ja tilasivuihisi
         setting_theme: Vaikuttaa Mastodonin ulkoasuun millä tahansa laitteella kirjauduttaessa.
       imports:
@@ -47,7 +41,6 @@ fi:
         setting_default_privacy: Julkaisun näkyvyys
         setting_default_sensitive: Merkitse media aina arkaluontoiseksi
         setting_delete_modal: Kysy vahvistusta ennen tuuttauksen poistamista
-        setting_display_sensitive_media: Näytä aina arkaluontoiseksi merkitty media
         setting_noindex: Jättäydy pois hakukoneindeksoinnista
         setting_reduce_motion: Vähennä animaatioiden liikettä
         setting_system_font_ui: Käytä järjestelmän oletusfonttia
diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml
index e510bd155f605244a9fb994bce89341789356072..730a6952258e8d50635ecdcc853f5785e6d11122 100644
--- a/config/locales/simple_form.fr.yml
+++ b/config/locales/simple_form.fr.yml
@@ -2,33 +2,44 @@
 fr:
   simple_form:
     hints:
+      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
+        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:
-        autofollow: Les personnes qui s'inscrivent grâce à l'invitation vous suivront automatiquement
-        avatar: Au format PNG, GIF ou JPG. 2 Mo maximum. Sera réduit à 400x400px
+        autofollow: Les personnes qui s’inscrivent grâce à l’invitation vous suivront automatiquement
+        avatar: Au format PNG, GIF ou JPG. %{size} maximum. Sera réduit à %{dimensions}px
         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
+        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
-        display_name:
-          one: <span class="name-counter">1</span> caractère restant
-          other: <span class="name-counter">%{count}</span> caractères restants
-        fields: Vous pouvez avoir jusqu'à 4 éléments affichés en tant que tableau sur votre profil
-        header: Au format PNG, GIF ou JPG. 2 Mo maximum. Sera réduit à 700x335px
+        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
+        inbox_url: Copiez l’URL depuis la page d’accueil du relais que vous souhaitez utiliser
         irreversible: Les pouets filtrés disparaîtront irrémédiablement, même si le filtre est supprimé plus tard
-        locale: La langue de l'interface-utilisateur, des courriels, et des notifications
+        locale: La langue de l’interface, des courriels et des notifications
         locked: Vous devrez approuver chaque abonné⋅e et vos statuts ne s’afficheront qu’à vos abonné⋅es
-        note:
-          one: <span class="note-counter">1</span> caractère restant
-          other: <span class="note-counter">%{count}</span> caractères restants
-        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_default_language: La langue de vos pouets peut être détectée automatiquement, mais ça n'est pas toujours pertinent
+        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_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.
+        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
       imports:
         data: Un fichier CSV généré par une autre instance de Mastodon
       sessions:
-        otp: 'Entrez le code d’authentification à deux facteurs généré par votre téléphone ou utilisez un de vos codes de récupération :'
+        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:
         chosen_languages: Lorsque coché, seuls les pouets dans les langues sélectionnées seront affichés sur les fils publics
     labels:
@@ -36,6 +47,18 @@ fr:
         fields:
           name: Étiquette
           value: Contenu
+      account_warning_preset:
+        text: Texte de présélection
+      admin_account_action:
+        send_email_notification: Notifier l'utilisateur par courriel
+        text: Attention personnalisée
+        type: Action
+        types:
+          disable: Désactiver
+          none: Ne rien faire
+          silence: Silence
+          suspend: Suspendre et effacer les données du compte de manière irréversible
+        warning_preset_id: Utiliser un modèle d'avertissement
       defaults:
         autofollow: Invitation à suivre votre compte
         avatar: Image de profil
@@ -46,27 +69,34 @@ fr:
         context: Contextes du filtre
         current_password: Mot de passe actuel
         data: Données
+        discoverable: Inscrire ce compte dans l'annuaire
         display_name: Nom public
         email: Adresse courriel
         expires_in: Expire après
         fields: Métadonnées du profil
         header: Image d’en-tête
+        inbox_url: URL de la boîte de relais
         irreversible: Supprimer plutôt que de cacher
-        locale: Langue de l'interface
+        locale: Langue de l’interface
         locked: Verrouiller le compte
-        max_uses: Nombre maximum d'utilisations
+        max_uses: Nombre maximum d’utilisations
         new_password: Nouveau mot de passe
         note: Présentation
         otp_attempt: Code d’identification à deux facteurs
         password: Mot de passe
         phrase: Mot-clé ou phrase
+        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
         setting_default_language: Langue de publication
         setting_default_privacy: Confidentialité des statuts
         setting_default_sensitive: Toujours marquer les médias comme sensibles
         setting_delete_modal: Afficher une fenêtre de confirmation avant de supprimer un pouet
-        setting_display_sensitive_media: Toujours afficher les médias marqués comme sensibles
+        setting_display_media: Affichage des médias
+        setting_display_media_default: Défaut
+        setting_display_media_hide_all: Masquer tout
+        setting_display_media_show_all: Montrer tout
+        setting_expand_spoilers: Toujours développer les pouets marqués d’un avertissement de contenu
         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
@@ -76,7 +106,8 @@ fr:
         severity: Sévérité
         type: Type d’import
         username: Identifiant
-        username_or_email: Nom d'utilisateur ou courriel
+        username_or_email: Nom d’utilisateur·ice ou courriel
+        whole_word: Mot entier
       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
@@ -88,6 +119,7 @@ fr:
         follow_request: Envoyer un courriel lorsque quelqu’un demande à me suivre
         mention: Envoyer un courriel lorsque quelqu’un me mentionne
         reblog: Envoyer un courriel lorsque quelqu’un partage mes statuts
+        report: Envoyer un courriel lorsqu’un nouveau rapport est soumis
     'no': Non
     required:
       mark: "*"
diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml
index 25694395deaddee77b1bf86155001efa86bc83c4..d5e0ef574aae9617a5e92f9a905836b047fb457c 100644
--- a/config/locales/simple_form.gl.yml
+++ b/config/locales/simple_form.gl.yml
@@ -2,29 +2,40 @@
 gl:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Vostede pode utilizar dar formato ao toot, como URLs, etiquetas e mencións
+      admin_account_action:
+        send_email_notification: A usuaria recibirá unha explicación sobre o que lle aconteceu a súa conta
+        text_html: Optativo. Pode utilizar formato no toot. Pode <a href="%{path}">engadir avisos preestablecidos</a> para aforrar tempo
+        type_html: Escolla que facer con <strong>%{acct}</strong>
+        warning_preset_id: Optativo. Poderá engadir texto personalizado ao final do preestablecido
       defaults:
         autofollow: As persoas que se conectaron a través de un convite seguirana automáticamente a vostede
-        avatar: PNG, GIF ou JPG.  Máximo 2MB. Será reducida a 400x400px
+        avatar: PNG, GIF ou JPG.  Máximo %{size}. Será reducida a %{dimensions}px
         bot: Esta conta realiza principalmente accións automatizadas e podería non estar monitorizada
         context: Un ou varios contextos onde se debería aplicar o filtro
-        digest: Enviar só tras un longo período de inactividade e só si recibeu algunha mensaxe personal na súa ausencia
-        display_name:
-          one: <span class="name-counter">1</span> caracter restante
-          other: <span class="name-counter">%{count}</span> caracteres restantes
+        digest: Enviar só tras un longo período de inactividade e só si recibeu algunha mensaxe persoal na súa ausencia
+        discoverable_html: O <a href="%{path}" target="_blank">directorio</a> permite atopar contas en función de intereses e actividade. Require ter ao menos %{min_followers} seguidoras
+        email: Enviaráselle un correo-e de confirmación
         fields: Pode ter ate 4 elementos no seu perfil mostrados como unha táboa
-        header: PNG, GIF ou JPG. Máximo 2MB. Será reducida a 700x335px
+        header: PNG, GIF ou JPG. Máximo %{size}. Será reducida a %{dimensions}px
+        inbox_url: Copiar o URL desde a páxina de inicio do repetidor que quere utilizar
         irreversible: Os toots filtrados desaparecerán de xeito irreversible, incluso si despois se elimina o filtro
         locale: O idioma da interface de usuaria, correos e notificacións
         locked: Require que vostede acepte as seguidoras de xeito manual
-        note:
-          one: <span class="note-counter">1</span> caracter restante
-          other: <span class="note-counter">%{count}</span> caracteres restantes
+        password: Utilice 8 caracteres ao menos
         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_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.
+        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
       imports:
         data: Ficheiro CSV exportado desde outra instancia Mastodon
       sessions:
@@ -36,6 +47,18 @@ gl:
         fields:
           name: Etiqueta
           value: Contido
+      account_warning_preset:
+        text: Texto preestablecido
+      admin_account_action:
+        send_email_notification: Notificar a usuaria por correo-e
+        text: Aviso personalizado
+        type: Acción
+        types:
+          disable: Desactivar
+          none: Non facer nada
+          silence: Acalar
+          suspend: Suspender e eliminar irreversiblemente datos da conta
+        warning_preset_id: Utilizar un aviso preestablecido
       defaults:
         autofollow: Convide a seguir a súa conta
         avatar: Avatar
@@ -46,11 +69,13 @@ gl:
         context: Contextos do filtro
         current_password: Contrasinal actual
         data: Datos
+        discoverable: Incluír esta conta no directorio
         display_name: Nome mostrado
         email: enderezo correo electrónico
         expires_in: Caducidade despois de
         fields: Metadatos do perfil
         header: Cabeceira
+        inbox_url: URL da caixa de entrada do repetidor
         irreversible: Soltar en lugar de agochar
         locale: Idioma da interface
         locked: Protexer conta
@@ -60,13 +85,18 @@ gl:
         otp_attempt: Código de Doble-Factor
         password: Contrasinal
         phrase: Palabra chave ou frase
+        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
         setting_default_language: Idioma de publicación
         setting_default_privacy: Intimidade da publicación
         setting_default_sensitive: Marcar sempre multimedia como sensible
         setting_delete_modal: Solicitar confirmación antes de eliminar unha mensaxe
-        setting_display_sensitive_media: Mostrar sempre os medios marcados como sensibles
+        setting_display_media: Mostrar medios
+        setting_display_media_default: Por omisión
+        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_noindex: Pedir non aparecer nas buscas dos motores de busca
         setting_reduce_motion: Reducir o movemento nas animacións
@@ -77,6 +107,7 @@ gl:
         type: Tipo de importación
         username: Nome de usuaria
         username_or_email: Nome de usuaria ou Correo-e
+        whole_word: Palabra completa
       interactions:
         must_be_follower: Bloquear as notificacións de non-seguidoras
         must_be_following: Bloquea as notificacións de personas que non segue
@@ -88,6 +119,7 @@ gl:
         follow_request: Enviar un correo cando alguén solicita seguila
         mention: Enviar un correo cando alguén a menciona
         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
     required:
       mark: "*"
diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml
index 96cdccd2b4b1ddaf8f2aeba93e81925a72e3cbe8..c86498c66aa99f893b2aff57786b12d50d086739 100644
--- a/config/locales/simple_form.he.yml
+++ b/config/locales/simple_form.he.yml
@@ -3,16 +3,10 @@ he:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF או JPG. מקסימום 2MB. גודל התמונה יוקטן ל-400x400px
+        avatar: PNG, GIF או JPG. מקסימום %{size}. גודל התמונה יוקטן ל-%{dimensions}px
         digest: נשלח לאחר תקופה ארוכה של אי-פעילות עם סיכום איזכורים שקיבלת בהעדרך
-        display_name:
-          one: נותרה אות<span class="name-counter">אחת</span>
-          other: נותרו<span class="name-counter">%{count}</span> אותיות
-        header: PNG, GIF או JPG. מקסימום 2MB. גודל התמונה יוקטן 700x335px
+        header: PNG, GIF או JPG. מקסימום %{size}. גודל התמונה יוקטן %{dimensions}px
         locked: מחייב אישור עוקבים באופן ידני. פרטיות ההודעות תהיה עוקבים-בלבד אלא אם יצוין אחרת
-        note:
-          one: נותרה אות<span class="note-counter">אחת</span>
-          other: נותרו <span class="note-counter">%{count}</span> אותיות
         setting_noindex: משפיע על הפרופיל הציבורי שלך ועמודי ההודעות
         setting_theme: משפיע על המראה של מסטודון בעת החיבור המזוהה מכל מכשיר שהוא.
       imports:
diff --git a/config/locales/simple_form.hr.yml b/config/locales/simple_form.hr.yml
index 6cff526ef91407489fdc13bb718e7f01f471f541..4b1d2b1e0a224163939faf39a443a5ed1a087917 100644
--- a/config/locales/simple_form.hr.yml
+++ b/config/locales/simple_form.hr.yml
@@ -3,11 +3,9 @@ hr:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF ili JPG. Najviše 2MB. Bit će smanjen na 400x400px
-        display_name: Najviše 30 znakova
-        header: PNG, GIF ili JPG. Najviše 2MB. Bit će smanjen na 700x335px
+        avatar: PNG, GIF ili JPG. Najviše %{size}. Bit će smanjen na %{dimensions}px
+        header: PNG, GIF ili JPG. Najviše %{size}. Bit će smanjen na %{dimensions}px
         locked: traži te da ručno odobriš sljedbenike i postavlja privatnost postova na dostupnu samo sljedbenicima
-        note: Najviše 65535 znakova
       imports:
         data: CSV fajl izvezen iz druge Mastodon instance
     labels:
diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml
index 2b36dc85b2faec2ffd6eaec0b807a28b2956b3ac..f36fabda1b91472014a988613abb751e991b281d 100644
--- a/config/locales/simple_form.hu.yml
+++ b/config/locales/simple_form.hu.yml
@@ -3,16 +3,10 @@ hu:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF vagy JPG. Maximum 2MB. Át lesz méretezve 400x400 pixelre
+        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
-        display_name:
-          one: <span class="name-counter">1</span>karakter maradt
-          other: <span class="name-counter">%{count}</span>karakter maradt
-        header: PNG, GIF vagy JPG. Maximum 2MB. Át lesz méretezve 700x335 pixelre
+        header: PNG, GIF vagy JPG. Maximum %{size}. Át lesz méretezve %{dimensions} pixelre
         locked: Egyenként engedélyezned kell a követőidet
-        note:
-          one: <span class="note-counter">1</span>karakter maradt
-          other: <span class="note-counter">%{count}</span>karakter maradt
         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.
       imports:
diff --git a/config/locales/simple_form.id.yml b/config/locales/simple_form.id.yml
index 76ea67cccbaf9b70d45e4607af339a1f2ffedf2f..c6da2beff3c3a9fe5a41dc05703cbeb46f1b72ce 100644
--- a/config/locales/simple_form.id.yml
+++ b/config/locales/simple_form.id.yml
@@ -3,11 +3,9 @@ id:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF atau JPG. Maksimal 2MB. Ukuran dikecilkan menjadi 400x400px
-        display_name: Maksimal 30 karakter
-        header: PNG, GIF atau JPG. Maksimal 2MB. Ukuran dikecilkan menjadi 700x335px
+        avatar: PNG, GIF atau JPG. Maksimal %{size}. Ukuran dikecilkan menjadi %{dimensions}px
+        header: PNG, GIF atau JPG. Maksimal %{size}. Ukuran dikecilkan menjadi %{dimensions}px
         locked: Anda harus menerima permintaan pengikut secara manual dan setting privasi postingan akan diubah khusus untuk pengikut
-        note: Maksimum 65535 karakter
       imports:
         data: File CSV yang diexpor dari server Mastodon lain
       sessions:
diff --git a/config/locales/simple_form.io.yml b/config/locales/simple_form.io.yml
index 94b12532c4b7ee44c778af56ead3798ee6fb2fda..c9fd9899e87332f4579cf799118052d6a6343489 100644
--- a/config/locales/simple_form.io.yml
+++ b/config/locales/simple_form.io.yml
@@ -3,11 +3,9 @@ io:
   simple_form:
     hints:
       defaults:
-        avatar: En la formato PNG, GIF o JPG. Til 2Mo. Esos mikrigita a 400x400px
-        display_name: 30 signi maxime
-        header: En la formato PNG, GIF o JPG. Til 2Mo. Esos mikrigita a 700x335px
+        avatar: En la formato PNG, GIF o JPG. Til %{size}. Esos mikrigita a %{dimensions}px
+        header: En la formato PNG, GIF o JPG. Til %{size}. Esos mikrigita a %{dimensions}px
         locked: Tu devos aprobar omna demandi di sequado, e tua mesaji esos senchanje nur por tua sequanti.
-        note: 65535 signi maxime
       imports:
         data: Dosiero CSV de altra instaluro di Mastodon
       sessions:
diff --git a/config/locales/simple_form.it.yml b/config/locales/simple_form.it.yml
index 185bba2055171633f8de23995aad976dea525f3a..dd43898d2536bc3faf717fe10407127c7904d5da 100644
--- a/config/locales/simple_form.it.yml
+++ b/config/locales/simple_form.it.yml
@@ -2,29 +2,40 @@
 it:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Puoi usare la sintassi dei toot, come URL, hashtag e menzioni
+      admin_account_action:
+        send_email_notification: L'utente riceverà una spiegazione di ciò che è successo con suo account
+        text_html: Opzionale. Puoi usare la sintassi dei toot. Puoi <a href="%{path}">aggiungere avvisi preimpostati</a> per risparmiare tempo
+        type_html: Decidi cosa fare con <strong>%{acct}</strong>
+        warning_preset_id: Opzionale. Puoi aggiungere un testo personalizzato alla fine di quello preimpostato
       defaults:
         autofollow: Le persone che si iscrivono attraverso l'invito ti seguiranno automaticamente
-        avatar: PNG, GIF o JPG. Al massimo 2MB. Verranno scalate a 400x400px
+        avatar: PNG, GIF o JPG. Al massimo %{size}. Verranno scalate a %{dimensions}px
         bot: Questo account esegue principalmente operazioni automatiche e potrebbe non essere tenuto sotto controllo da una persona
         context: Uno o più contesti nei quali il filtro dovrebbe essere applicato
         digest: Inviata solo dopo un lungo periodo di inattività e solo se hai ricevuto qualche messaggio personale in tua assenza
-        display_name:
-          one: <span class="name-counter">1</span> carattere rimanente
-          other: <span class="name-counter">%{count}</span> caratteri rimanenti
+        discoverable_html: La <a href="%{path}" target="_blank">directory</a> permette alle persone di trovare account in base a determinati interessi o attività. Richiede almeno %{min_followers} seguaci
+        email: Ti manderemo una email di conferma
         fields: Puoi avere fino a 4 voci visualizzate come una tabella sul tuo profilo
-        header: PNG, GIF o JPG. Al massimo 2MB. Verranno scalate a 700x335px
+        header: PNG, GIF o JPG. Al massimo %{size}. Verranno scalate a %{dimensions}px
+        inbox_url: Copia la URL dalla pagina iniziale del ripetitore che vuoi usare
         irreversible: I toot filtrati scompariranno in modo irreversibile, anche se il filtro viene eliminato
         locale: La lingua dell'interfaccia utente, di email e notifiche push
         locked: Richiede che approvi i follower manualmente
-        note:
-          one: <span class="note-counter">1</span> carattere rimanente
-          other: <span class="note-counter">%{count}</span> caratteri rimanenti
+        password: Usa almeno 8 caratteri
         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_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.
+        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
       imports:
         data: File CSV esportato da un'altra istanza di Mastodon
       sessions:
@@ -36,6 +47,18 @@ it:
         fields:
           name: Etichetta
           value: Contenuto
+      account_warning_preset:
+        text: Testo preimpostato
+      admin_account_action:
+        send_email_notification: Informa l'utente via email
+        text: Avviso personalizzato
+        type: Azione
+        types:
+          disable: Disabilita
+          none: Non fare nulla
+          silence: Silenzia
+          suspend: Sospendi e cancella i dati dell'account in modo irreversibile
+        warning_preset_id: Usa un avviso preimpostato
       defaults:
         autofollow: Invita a seguire il tuo account
         avatar: Avatar
@@ -46,39 +69,47 @@ it:
         context: Contesti del filtro
         current_password: Password corrente
         data: Data
+        discoverable: Inserisci questo account nella directory
         display_name: Nome visualizzato
         email: Indirizzo email
         expires_in: Scade dopo
         fields: Metadati del profilo
-        header: Header
+        header: Intestazione
+        inbox_url: URL della inbox del ripetitore
         irreversible: Elimina invece di nascondere
         locale: Lingua dell'interfaccia
         locked: Blocca account
         max_uses: Numero massimo di utilizzi
         new_password: Nuova password
-        note: Bio
+        note: Biografia
         otp_attempt: Codice due-fattori
         password: Password
         phrase: Parola chiave o frase
+        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
         setting_default_language: Lingua dei post
         setting_default_privacy: Privacy dei post
         setting_default_sensitive: Segna sempre i media come sensibili
         setting_delete_modal: Mostra dialogo di conferma prima di eliminare un toot
-        setting_display_sensitive_media: Mostra sempre i media segnati come sensibili
+        setting_display_media: Visualizzazione dei media
+        setting_display_media_default: Predefinita
+        setting_display_media_hide_all: Nascondi tutti
+        setting_display_media_show_all: Mostra tutti
+        setting_expand_spoilers: Espandi sempre toot con content warning
         setting_hide_network: Nascondi la tua rete
-        setting_noindex: Non indicizzare dai motori di ricerca
+        setting_noindex: Non farti indicizzare dai motori di ricerca
         setting_reduce_motion: Riduci movimento nelle animazioni
-        setting_system_font_ui: Usa il carattere di default del sistema
+        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
         severity: Severità
         type: Tipo importazione
         username: Nome utente
         username_or_email: Nome utente o email
+        whole_word: Parola intera
       interactions:
-        must_be_follower: Blocca notifiche dai non follower
+        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
       notification_emails:
@@ -88,6 +119,7 @@ it:
         follow_request: Invia email quando qualcuno richiede di seguirti
         mention: Invia email quando qualcuno ti menziona
         reblog: Invia email quando qualcuno da un boost al tuo stato
+        report: Manda una mail quando viene inviato un nuovo rapporto
     'no': 'No'
     required:
       mark: "*"
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index 7f7f3af19dd3ce06725aa341ff58ece4322a6955..f9beedb7e1b1125be4ae710527881b9553d00187 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -2,25 +2,40 @@
 ja:
   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: 2MBまでのPNG、GIF、JPGが利用可能です。400x400pxまで縮小されます
+        avatar: "%{size}までのPNG、GIF、JPGが利用可能です。%{dimensions}pxまで縮小されます"
         bot: このアカウントは主に自動で動作し、人が見ていない可能性があります
         context: フィルターを適用する対象 (複数選択可)
         digest: 長期間使用していない場合と不在時に返信を受けた場合のみ送信されます
-        display_name: あと<span class="name-counter">%{count}</span>文字入力できます。
+        discoverable_html: <a href="%{path}" target="_blank">ディレクトリ</a> は興味や活動をもとにアカウントを見つけることを可能にします。 掲載には %{min_followers} 人以上のフォロワーが必要です
+        email: 確認のメールが送信されます
         fields: プロフィールに表として4つまでの項目を表示することができます
-        header: 2MBまでのPNG、GIF、JPGが利用可能です。 700x335pxまで縮小されます
+        header: "%{size}までのPNG、GIF、JPGが利用可能です。 %{dimensions}pxまで縮小されます"
+        inbox_url: 使用したいリレーサーバーのトップページからURLをコピーします
         irreversible: フィルターが後で削除されても、除外されたトゥートは元に戻せなくなります
         locale: ユーザーインターフェース、メールやプッシュ通知の言語
         locked: フォロワーを手動で承認する必要があります
-        note: あと<span class="note-counter">%{count}</span>文字入力できます。
+        password: 少なくとも8文字は入力してください
         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:
         data: 他の Mastodon インスタンスからエクスポートしたCSVファイルを選択して下さい
       sessions:
@@ -32,6 +47,18 @@ ja:
         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: アイコン
@@ -39,14 +66,16 @@ ja:
         chosen_languages: 表示する言語
         confirm_new_password: 新しいパスワード(確認用)
         confirm_password: パスワード(確認用)
-        context: フィルター対象
+        context: 除外対象
         current_password: 現在のパスワード
         data: データ
+        discoverable: ディレクトリに掲載する
         display_name: 表示名
         email: メールアドレス
         expires_in: 有効期限
         fields: プロフィール補足情報
         header: ヘッダー
+        inbox_url: リレーサーバーの inbox URL
         irreversible: 隠すのではなく除外する
         locale: 言語
         locked: 承認制アカウントにする
@@ -55,14 +84,19 @@ ja:
         note: プロフィール
         otp_attempt: 二段階認証コード
         password: パスワード
-        phrase: 単語または語句
+        phrase: キーワードまたはフレーズ
+        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_sensitive_media: 閲覧注意としてマークされたメディアも常に表示する
+        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: アニメーションの動きを減らす
@@ -73,6 +107,7 @@ ja:
         type: インポートする項目
         username: ユーザー名
         username_or_email: ユーザー名またはメールアドレス
+        whole_word: 単語全体にマッチ
       interactions:
         must_be_follower: フォロワー以外からの通知をブロック
         must_be_following: フォローしていないユーザーからの通知をブロック
@@ -84,6 +119,7 @@ ja:
         follow_request: フォローリクエストを受けた時にメールで通知する
         mention: 返信が来た時にメールで通知する
         reblog: トゥートがブーストされた時にメールで通知する
+        report: 通報を受けた時にメールで通知する
     'no': いいえ
     required:
       mark: "*"
diff --git a/config/locales/simple_form.ka.yml b/config/locales/simple_form.ka.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6bccb3134629d352ab84c7dba25a6d9308aa5468
--- /dev/null
+++ b/config/locales/simple_form.ka.yml
@@ -0,0 +1,92 @@
+---
+ka:
+  simple_form:
+    hints:
+      defaults:
+        autofollow: ადამიანები რომლებიც დარეგისტრირდებიან მოწვევით, ავტომატურად გამოგყვებიან
+        avatar: პნგ, გიფ ან ჯპგ. მაქს. %{size}. ზომა დაპატარავდება %{dimensions}პიქს.-ზე
+        bot: ეს ანგარიში უმთავრესად ასრულებს ავტომატურ მოქმედებებს და შესაძლოა არ იყოს მონიტორინგის ქვეშ
+        context: ერთ ან მრავალი კონტექსტი სადაც ფილტრი უნდა შესრულდეს
+        digest: იგზავნება მხოლოდ ხანგრძლივი უაქტივობის პერიოდის შემდეგ და არყოფნისას თუ მიიღეთ ერთი წერილი მაინც
+        fields: პროფილზე ტაბულის სახით შესაძლოა საჩვენებლად გაგაჩნდეთ მაქს. 4 პუნქტი
+        header: პნგ, გიფ ან ჯპგ. მაქს. %{size}. ზომა დაპატარავდება %{dimensions}პიქს.-ზე
+        inbox_url: ურლ დააკოირეთ გამოყენებისთვის სასურველი რილეის წინა გვერდიდან
+        irreversible: გაფილტრული ტუტები გაუქმდება აღუდგენლად, იმ შემთხვევაშიც კი თუ ფილტრი სამომავლოდ გაუქმდება
+        locale: მომხმარებლის ინტერფეისის, ელ-ფოსტის წერილების და ფუშ შეტყობინებების ენა
+        locked: საჭიროებს თქვენ მიერ მიმდევრების ხელით დადასტურებას
+        phrase: დამთხვევა მოხდება დიდი და პატარა ასოების ან კონტენტის გაფრთხილების გათვალისწინების გარეშე
+        scopes: რომელი აპიებისადმი ექნება აპლიკაციას ცვდომა. თუ არიჩევთ უმთავრეს ფარგლებს, არ დაგჭირდებათ ინდივიდუალურების ამორჩევა.
+        setting_default_language: თქვენი ტუტების ენა შეიძლება დადგინდეს ავტომატურად, მაგრამ ეს არაა ყოველთვის ზუსტი
+        setting_hide_network: ვის მიყვებით და ვინ მოგყვებათ არ გამოჩნდება აქ
+        setting_noindex: გავლენას ახდენს თქვენს ღია პროფილისა და სტატუსის გვერდებზე
+        setting_theme: გავლენას ახდენს თუ როგორ გამოიყურება მასტოდონი, როდესაც შესული ხართ რომელიმე მოწყობილობიდან.
+        whole_word: როდესაც სიტყვა ან ფრაზა მხოლოდ ალფა-ნუმერიკულია, ის დაფიქსირდება თუ ემთხვევა სრულ სიტყვას
+      imports:
+        data: ცსვ ფაილის ექსპორტი მოხდა მასტოდონის სხვა ინსტანციიდან
+      sessions:
+        otp: 'შეიყვანეთ მეორე ფაქტორის კოდი, რომელიც დააგერირა თქვენმა ტელეფონმა ან მოიხმარეთ შემდეგი აღდგენის კოდებიდან ერთ-ერთი:'
+      user:
+        chosen_languages: როდესაც მოინიშნება, ღია თაიმლაინზე გამოჩნდება ტუტები მხოლოდ არჩეულ ენებზე
+    labels:
+      account:
+        fields:
+          name: ლეიბლი
+          value: მოცულობა
+      defaults:
+        autofollow: მოიწვიეთ რომ გამოჰყვნენ თქვენს ანგარიშს
+        avatar: ავატარი
+        bot: ეს ბოტის ანგარიშია
+        chosen_languages: ენების ფილტრი
+        confirm_new_password: დაადასტურეთ ახალი პაროლი
+        confirm_password: დაადასტურეთ პაროლი
+        context: კონტექსტის ფილტრი
+        current_password: მიმდინარე პაროლი
+        data: მონაცემები
+        display_name: დისპლეის სახელი
+        email: ელ-ფოსტის მისამართი
+        expires_in: ვადის გასვლის დრო
+        fields: პროფილის მეტა-მონაცემი
+        header: დასათაურება
+        inbox_url: რილეი ინბოქსის ურლ
+        irreversible: გაუქმდეს დამალვის მაგივრად
+        locale: ინტერფეისის ენა
+        locked: ანგარიშის ჩაკეტვა
+        max_uses: მოხმარების მაქს. ოდენობა
+        new_password: ახალი პაროლი
+        note: ბიო.
+        otp_attempt: მეორე-ფაქტორის კოდი
+        password: პაროლი
+        phrase: სიტყვა ან ფრაზა
+        setting_auto_play_gif: ანიმაციური გიფების ავტო-დაკვრა
+        setting_boost_modal: ბუსტამე მოხდეს დამოწმება
+        setting_default_language: პოსტინგის ენა
+        setting_default_privacy: პოსტის კონფიდენციალურობა
+        setting_default_sensitive: ყოველთვის მოინიშნოს მედია მგრძნობიარედ
+        setting_delete_modal: ტუტის გაუქმებამდე გამოჩნდეს დადასტურების ფანჯარა
+        setting_hide_network: თქვენი ქსელის დამალვა
+        setting_noindex: საძოები სისტემების ინდექსაციის შეჩერება
+        setting_reduce_motion: მოძრაობის შემცირება ანიმაციებში
+        setting_system_font_ui: მოხდეს სისტემის საწყისი ფონტის მოხმარება
+        setting_theme: საიტის თემა
+        setting_unfollow_modal: გამოჩნდეს დადასტურების ფანჯარა, სანამ შეყვეტთ ვინმეს დადევნებას
+        severity: სიმძიმე
+        type: იმპორტის სახეობა
+        username: მომხმარებლის სახელი
+        username_or_email: მომხმარებლის სახელი ან ელ-ფოსტა
+        whole_word: მთელი სიტყვა
+      interactions:
+        must_be_follower: დაიბლოკოს შეტყობინებები არა მიმდევრებისგან
+        must_be_following: დაიბლოკოს შეტყობინებები ადამიანებისგან ვისაც არ მიჰყვებით
+        must_be_following_dm: დაიბლოკოს პირადი წერილები ადამიანბისგან ვისაც არ მიჰყვებით
+      notification_emails:
+        digest: გამოიგზავნოს დაიჯესტ წერილები
+        favourite: გამოიგზავნოს წერილი როდესაც ვინმე ფავორიტად აქცევს თქვენს სტატუსს
+        follow: გამოიგზავნოს წერილი როდესაც ვინმე გამოგყვებათ
+        follow_request: გამოიგზავნოს წერილი როდესაც ვინმე მოგთხოვთ გაჰყვეთ
+        mention: გამოიგზავნოს წერილი როდესაც ვინმე გასახელებთ
+        reblog: გამოიგზავნოს წერილი როდესაც ვინმე გაზრდის თქვენს სტატუსს
+    'no': არა
+    required:
+      mark: "*"
+      text: აუცილებელი
+    'yes': კი
diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml
index e0a6a74052b2ca18aa129a106952e39b9631dc82..fd0a1940ee12abd04ba12daf7336048d35fc125a 100644
--- a/config/locales/simple_form.ko.yml
+++ b/config/locales/simple_form.ko.yml
@@ -2,28 +2,40 @@
 ko:
   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: PNG, GIF 혹은 JPG. 최대 2MB. 400x400px로 다운스케일 될 것임
+        avatar: PNG, GIF 혹은 JPG. 최대 %{size}. %{dimensions}px로 다운스케일 될 것임
         bot: 사람들에게 계정이 사람이 아님을 알립니다
         context: 필터를 적용 할 한 개 이상의 컨텍스트
         digest: 오랫동안 활동하지 않았을 때 받은 멘션들에 대한 요약 받기
-        display_name:
-          one: <span class="name-counter">1</span> 글자 남음
-          other: <span class="name-counter">%{count}</span> 글자 남음
+        discoverable_html: <a href="%{path}" target="_blank">디렉토리</a> 는 사람들의 관심사와 활동에 관련 된 계정들을 찾을 수 있게 해 줍니다. 최소 %{min_followers}명의 팔로어가 필요합니다
+        email: 당신은 확인 메일을 받게 됩니다
         fields: 당신의 프로파일에 최대 4개까지 표 형식으로 나타낼 수 있습니다
-        header: PNG, GIF 혹은 JPG. 최대 2MB. 700x335px로 다운스케일 됨
+        header: PNG, GIF 혹은 JPG. 최대 %{size}. %{dimensions}px로 다운스케일 됨
+        inbox_url: 사용 할 릴레이 서버의 프론트페이지에서 URL을 복사합니다
         irreversible: 필터링 된 툿은 나중에 필터가 사라지더라도 돌아오지 않게 됩니다
         locale: 유저 인터페이스, 이메일, 푸시 알림 언어
         locked: 수동으로 팔로워를 승인하고, 기본 툿 프라이버시 설정을 팔로워 전용으로 변경
-        note:
-          one: <span class="note-counter">1</span> 글자 남음
-          other: <span class="note-counter">%{count}</span> 글자 남음
+        password: 최소 8글자
         phrase: 툿 내용이나 CW 내용 안에서 대소문자 구분 없이 매칭 됩니다
+        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:
         data: 다른 마스토돈 인스턴스에서 추출된 CSV 파일
       sessions:
@@ -35,6 +47,18 @@ ko:
         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: 아바타
@@ -45,11 +69,13 @@ ko:
         context: 필터 컨텍스트
         current_password: 현재 비밀번호 입력
         data: 데이터
+        discoverable: 이 계정을 디렉토리에서 찾을 수 있도록 합니다
         display_name: 표시되는 이름
         email: 이메일 주소
         expires_in: 만료시각
         fields: 프로필 메타데이터
         header: 헤더
+        inbox_url: 릴레이 서버의 inbox URL
         irreversible: 숨기는 대신 삭제
         locale: 인터페이스 언어
         locked: 계정 잠금
@@ -59,13 +85,18 @@ ko:
         otp_attempt: 2단계 인증 코드
         password: 비밀번호
         phrase: 키워드 또는 문장
+        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_sensitive_media: 열람주의로 설정 된 이미지도 항상 보여주기
+        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: 애니메이션 줄이기
@@ -76,6 +107,7 @@ ko:
         type: 불러오기 종류
         username: 유저 이름
         username_or_email: 유저네임 또는 이메일
+        whole_word: 단어 전체에 매칭
       interactions:
         must_be_follower: 나를 팔로우 하지 않는 사람에게서 온 알림을 차단
         must_be_following: 내가 팔로우 하지 않는 사람에게서 온 알림을 차단
@@ -87,6 +119,7 @@ ko:
         follow_request: 누군가 나를 팔로우 하길 원할 때 이메일 보내기
         mention: 누군가 나에게 답장했을 때 이메일 보내기
         reblog: 누군가 내 툿을 부스트 했을 때 이메일 보내기
+        report: 새 신고 등록시 이메일로 알리기
     'no': 아니오
     required:
       mark: "*"
diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml
index eb13ec1950d5707c6ba697e9ee22b34872ff459b..6eb784c303eacf5f998fedda54e542c1a74d1e60 100644
--- a/config/locales/simple_form.nl.yml
+++ b/config/locales/simple_form.nl.yml
@@ -2,33 +2,44 @@
 nl:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Je kunt voor toots specifieke tekst gebruiken, zoals URL's, hashtags en vermeldingen
+      admin_account_action:
+        send_email_notification: De gebruiker ontvangt een uitleg over wat er met hun account is gebeurd
+        text_html: Optioneel. Je kunt voor toots specifieke tekst gebruiken. Om tijd te besparen kun je <a href="%{path}">voorinstellingen van waarschuwingen toevoegen</a>
+        type_html: Kies wat er met <strong>%{acct}</strong> moet gebeuren
+        warning_preset_id: Optioneel. Je kunt nog steeds handmatig tekst toevoegen aan het eind van de voorinstelling
       defaults:
         autofollow: Mensen die zich via de uitnodiging hebben geregistreerd, volgen jou automatisch
-        avatar: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 400x400px
+        avatar: PNG, GIF of JPG. Maximaal %{size}. Wordt teruggeschaald naar %{dimensions}px
         bot: Dit is een geautomatiseerd account en wordt mogelijk niet gemonitord
         context: Een of meerdere locaties waar de filter actief moet zijn
         digest: Wordt alleen na een lange periode van inactiviteit verzonden en alleen wanneer je tijdens jouw afwezigheid persoonlijke berichten hebt ontvangen
-        display_name:
-          one: <span class="name-counter">1</span> teken over
-          other: <span class="name-counter">%{count}</span> tekens over
+        discoverable_html: In de <a href="%{path}" target="_blank">gebruikersgids</a> kunnen mensen andere accounts vinden aan de hand van interesses en activiteit. Dit vereist tenminste %{min_followers} volgers
+        email: Je krijgt een bevestigingsmail
         fields: Je kan maximaal 4 items als een tabel op je profiel weergeven
-        header: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 700x335px
+        header: PNG, GIF of JPG. Maximaal %{size}. Wordt teruggeschaald naar %{dimensions}px
+        inbox_url: Kopieer de URL van de voorpagina van de relayserver die je wil gebruiken
         irreversible: Gefilterde toots verdwijnen onomkeerbaar, zelfs als de filter later wordt verwijderd
         locale: De taal van de gebruikersomgeving, e-mails en pushmeldingen
         locked: Vereist dat je handmatig volgers moet accepteren
-        note:
-          one: <span class="note-counter">1</span> teken over
-          other: <span class="note-counter">%{count}</span> tekens over
+        password: Gebruik tenminste 8 tekens
         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_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).
+        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
       imports:
         data: CSV-bestand dat op een andere Mastodonserver werd geëxporteerd
       sessions:
-        otp: Voer de tweestaps-aanmeldcode vanaf jouw mobiele telefoon in of gebruik een van jouw herstelcodes.
+        otp: 'Voer de tweestaps-aanmeldcode vanaf jouw mobiele telefoon in of gebruik een van jouw herstelcodes:'
       user:
         chosen_languages: Alleen toots in de aangevinkte talen worden op de openbare tijdlijnen getoond
     labels:
@@ -36,6 +47,18 @@ nl:
         fields:
           name: Label
           value: Inhoud
+      account_warning_preset:
+        text: Tekst van voorinstelling
+      admin_account_action:
+        send_email_notification: Meld dit per e-mail aan de gebruiker
+        text: Aangepaste waarschuwing
+        type: Actie
+        types:
+          disable: Uitschakelen
+          none: Niets doen
+          silence: Negeren
+          suspend: Opschorten en onomkeerbaar accountgegevens verwijderen
+        warning_preset_id: Gebruik een voorinstelling van een waarschuwing
       defaults:
         autofollow: Uitnodigen om jouw account te volgen
         avatar: Avatar
@@ -46,11 +69,13 @@ nl:
         context: Filterlocaties
         current_password: Huidig wachtwoord
         data: Gegevens
+        discoverable: Dit account in de gebruikersgids tonen
         display_name: Weergavenaam
         email: E-mailadres
         expires_in: Vervalt na
         fields: Metadata profiel
         header: Omslagfoto
+        inbox_url: Inbox-URL van de relayserver
         irreversible: Verwijderen in plaats van verbergen
         locale: Taal van de gebruikersomgeving
         locked: Maak account besloten
@@ -60,13 +85,18 @@ nl:
         otp_attempt: Tweestaps-aanmeldcode
         password: Wachtwoord
         phrase: Trefwoord of zinsdeel
+        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
         setting_default_language: Taal van jouw toots
         setting_default_privacy: Standaardzichtbaarheid van jouw toots
         setting_default_sensitive: Media altijd als gevoelig markeren
         setting_delete_modal: Vraag voor het verwijderen van een toot een bevestiging
-        setting_display_sensitive_media: Als gevoelig gemarkeerde media altijd tonen
+        setting_display_media: Mediaweergave
+        setting_display_media_default: Standaard
+        setting_display_media_hide_all: Alles verbergen
+        setting_display_media_show_all: Alles tonen
+        setting_expand_spoilers: Altijd toots met tekstwaarschuwingen uitklappen
         setting_hide_network: Jouw volgers en wie je volgt verbergen
         setting_noindex: Jouw toots niet door zoekmachines laten indexeren
         setting_reduce_motion: Langzamere animaties
@@ -77,17 +107,19 @@ nl:
         type: Importtype
         username: Gebruikersnaam
         username_or_email: Gebruikersnaam of e-mailadres
+        whole_word: Heel woord
       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
       notification_emails:
         digest: Periodiek e-mails met een samenvatting versturen
-        favourite: Een e-mail versturen wanneer iemand jouw toot als favoriet markeert
+        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
         reblog: Een e-mail versturen wanneer iemand jouw toot heeft geboost
+        report: Verstuur een e-mail wanneer een nieuw rapportage is ingediend
     'no': Nee
     required:
       mark: "*"
diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml
index aba8feeb610c7e995575c58028d7ca409c887bda..fc339c3f27b633b9fd6fc55c8d93052241a95ccf 100644
--- a/config/locales/simple_form.no.yml
+++ b/config/locales/simple_form.no.yml
@@ -3,16 +3,10 @@
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF eller JPG. Maksimalt 2 MB. Vil bli nedskalert til 400x400px
+        avatar: PNG, GIF eller JPG. Maksimalt %{size}. Vil bli nedskalert til %{dimensions}px
         digest: Kun sendt etter en lang periode med inaktivitet og bare dersom du har mottatt noen personlige meldinger mens du var borte
-        display_name:
-          one: <span class="name-counter">1</span> tegn igjen
-          other: <span class="name-counter">%{count}</span> tegn igjen
-        header: PNG, GIF eller JPG. Maksimalt 2MB. Vil bli nedskalert til 700x335px
+        header: PNG, GIF eller JPG. Maksimalt %{size}. Vil bli nedskalert til %{dimensions}px
         locked: Krever at du manuelt godkjenner følgere
-        note:
-          one: <span class="note-counter">1</span> tegn igjen
-          other: <span class="note-counter">%{count}</span> tegn igjen
         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:
diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml
index 7d11d0d3fef8f9a03d1b1308250eb973de7e882f..6ded448e903373c173609b0293442e1408fbbade 100644
--- a/config/locales/simple_form.oc.yml
+++ b/config/locales/simple_form.oc.yml
@@ -2,33 +2,44 @@
 oc:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Podètz utilizar la sintaxi dels tuts, coma las URL, las etiquetas e las mencions
+      admin_account_action:
+        send_email_notification: L’utilizaire recebrà una explicacion de çò qu’arribèt a son compte
+        text_html: Opcional. Podètz utilizar la sintaxi dels tuts. Podètz <a href="%{path}">ajustar un avertiment personalizat</a> per estalviar de temps
+        type_html: Causir de qué far amb <strong>%{acct}</strong>
+        warning_preset_id: Opcional. Podètz ajustar un tèxt personalizat a a fin de çò predefinit
       defaults:
         autofollow: Lo monde que se marcan gràcia a l’invitacion vos segràn automaticament
-        avatar: PNG, GIF o JPG. Maximum 2 Mo. Serà retalhat en 400x400px
+        avatar: PNG, GIF o JPG. Maximum %{size}. Serà retalhat en %{dimensions}px
         bot: Avisar lo monde qu’aqueste compte es pas d’una persona
         context: Un o mai de contèxtes ont lo filtre deuriá s’aplicar
         digest: Solament enviat aprèp un long moment d’inactivitat e solament s’avètz recebut de messatges personals pendent vòstra abséncia
-        display_name:
-          one: Demòra encara <span class="name-counter">1</span> caractèr
-          other: Demòran encara <span class="name-counter">%{count}</span> caractèrs
+        discoverable_html: L’<a href="%{path}" target="_blank">annuari</a> permet al monde de trobar de comptes segon lor interèsses e activitats. Requerís almens %{min_followers} seguidors
+        email: Vos mandarem un corrièl de confirmacion
         fields: Podètz far veire cap a 4 elements sus vòstre perfil
-        header: PNG, GIF o JPG. Maximum 2 Mo. Serà retalhada en 700x335px
+        header: PNG, GIF o JPG. Maximum %{size}. Serà retalhada en %{dimensions}px
+        inbox_url: Copiatz l’URL de la pagina màger del relai que volètz utilizar
         irreversible: Los tuts filtrats desapareisseràn irreversiblament, encara que lo filtre siá suprimit mai tard
         locale: La lenga de l’interfàcia d’utilizacion, los messatges e las notificacions
         locked: Demanda qu’acceptetz manualament lo mond que vos sègon e botarà la visibilitat de vòstras publicacions coma accessiblas a vòstres seguidors solament
-        note:
-          one: Demòra encara <span class="name-counter">1</span> caractèr
-          other: Demòran encara <span class="name-counter">%{count}</span> caractèrs
+        password: Utilizatz almens 8 caractèrs
         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.
+        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
       imports:
         data: Fichièr CSV exportat d’una autra instància Mastodon
       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 :'
+        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:
         chosen_languages: Quand seleccionadas, solament los tuts dins las lengas triadas seràn mostrats dins vòstre flux d’actualitat
     labels:
@@ -36,6 +47,18 @@ oc:
         fields:
           name: Nom
           value: Contengut
+      account_warning_preset:
+        text: Tèxt predefinit
+      admin_account_action:
+        send_email_notification: Avisar l’utilizaire per corrièl
+        text: Avertiment personalizat
+        type: Accions
+        types:
+          disable: Desactivar
+          none: Far pas res
+          silence: Metre en silence
+          suspend: Suspendre e escafar per de bon las donadas del compte
+        warning_preset_id: Utilizar un avertiment predefinit
       defaults:
         autofollow: Convidar a sègre vòstre compte
         avatar: Avatar
@@ -46,11 +69,13 @@ oc:
         context: Contèxte del filtre
         current_password: Senhal actual
         data: Donadas
+        discoverable: Far aparéisser aqueste compte a l’annuari
         display_name: Escais
         email: Corrièl
         expires_in: Expira aprèp
         fields: Metadonada del perfil
         header: Bandièra
+        inbox_url: URL de la bóstia de recepcion del relai
         irreversible: Suprimir allòc de rescondre
         locale: Lenga de l’interfàcia
         locked: Far venir lo compte privat
@@ -60,23 +85,29 @@ oc:
         otp_attempt: Còdi Two-factor
         password: Senhal
         phrase: Senhal o frasa
+        setting_aggregate_reblogs: Agropar los partatges dins lo flux d’actualitat
         setting_auto_play_gif: Lectura automatica dels GIFS animats
-        setting_boost_modal: Afichar una fenèstra de confirmacion abans de partejar un estatut
+        setting_boost_modal: Mostrar una fenèstra de confirmacion abans de partejar un estatut
         setting_default_language: Lenga de publicacion
-        setting_default_privacy: Confidencialitat de las publicacions
+        setting_default_privacy: Confidencialitat dels tuts
         setting_default_sensitive: Totjorn marcar los mèdias coma sensibles
         setting_delete_modal: Mostrar una fenèstra de confirmacion abans de suprimir un estatut
-        setting_display_sensitive_media: Totjorn mostrar los mèdias coma sensibles
+        setting_display_media: Afichatge dels mèdias
+        setting_display_media_default: Defaut
+        setting_display_media_hide_all: O rescondre tot
+        setting_display_media_show_all: O mostrar tot
+        setting_expand_spoilers: Totjorn desplegar los tuts marcats amb un avertiment de contengut
         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_system_font_ui: Utilizar la polissa del sisèma
+        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
         severity: Severitat
         type: Tipe d’impòrt
         username: Nom d’utilizaire
         username_or_email: Nom d’utilizaire o corrièl
+        whole_word: Mot complèt
       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
@@ -88,6 +119,7 @@ oc:
         follow_request: Enviar un corrièl quand qualqu’un demanda de vos sègre
         mention: Enviar un corrièl quand qualqu’un vos menciona
         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: "*"
diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml
index 55c5e1c6d7f9715766aeab83d8172dacb77df255..bbc55e8a913fa06a214f5199160a267216846dc0 100644
--- a/config/locales/simple_form.pl.yml
+++ b/config/locales/simple_form.pl.yml
@@ -2,32 +2,40 @@
 pl:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Możesz korzystać ze składni której używasz we wpisach, takiej jak adresy URL, hashtagi i wspomnienia
+      admin_account_action:
+        send_email_notification: Użytkownik otrzyma informację, co stało się z jego kontem
+        text_html: Możesz używać składni której używasz we wpisach. Możesz <a href="%{path}">dodać szablon ostrzeżenia</a> aby zaoszczędzić czas
+        type_html: Wybierz co chcesz zrobić z <strong>%{acct}</strong>
+        warning_preset_id: Nieobowiązkowe. Możesz dodać niestandardowy tekst do końcowki szablonu
       defaults:
         autofollow: Osoby, które zarejestrują się z Twojego zaproszenia automatycznie zaczną Cię śledzić
-        avatar: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 400x400px
+        avatar: PNG, GIF lub JPG. Maksymalnie %{size}. Zostanie zmniejszony do %{dimensions}px
         bot: To konto wykonuje głównie zautomatyzowane działania i może nie być monitorowane
         context: Jedno lub wiele miejsc, w których filtr zostanie zastosowany
         digest: Wysyłane tylko po długiej nieaktywności, jeżeli w tym czasie otrzymaleś jakąś wiadomość bezpośrednią
-        display_name:
-          few: Pozostały <span class="name-counter">%{count}</span> znaki.
-          many: Pozostało <span class="name-counter">%{count}</span> znaków
-          one: Pozostał <span class="name-counter">1</span> znak
-          other: Pozostało <span class="name-counter">%{count}</span> znaków
+        discoverable_html: <a href="%{path}" target="_blank">Katalog</a> pozwala znaleźć konta na podstawie zainteresowań i aktywności. Profil musi śledzić przynajmniej %{min_followers} osób
+        email: Otrzymasz e-mail potwierdzajÄ…cy
         fields: Możesz ustawić maksymalnie 4 niestandardowe pola wyświetlane jako tabela na Twoim profilu
-        header: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 700x335px
+        header: PNG, GIF lub JPG. Maksymalnie %{size}. Zostanie zmniejszony do %{dimensions}px
+        inbox_url: Skopiuj adres ze strony głównej przekaźnika, którego chcesz użyć
         irreversible: Filtrowane wpisy znikną bezpowrotnie, nawet gdy filtr zostanie usunięty
         locale: Język interfejsu, wiadomości e-mail i powiadomieniach push
         locked: Musisz akceptować prośby o śledzenie
-        note:
-          few: Pozostały <span class="name-counter">%{count}</span> znaki.
-          many: Pozostało <span class="name-counter">%{count}</span> znaków
-          one: Pozostał <span class="name-counter">1</span> znak
-          other: Pozostało <span class="name-counter">%{count}</span> znaków
+        password: Użyj co najmniej 8 znaków
         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_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_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.
+        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ń
       imports:
         data: Plik CSV wyeksportowany z innej instancji Mastodona
       sessions:
@@ -39,6 +47,18 @@ pl:
         fields:
           name: Nazwa
           value: Zawartość
+      account_warning_preset:
+        text: Tekst szablonu
+      admin_account_action:
+        send_email_notification: Powiadom użytkownika mailem
+        text: Niestandardowe ostrzeżenie
+        type: Działanie
+        types:
+          disable: Wyłącz
+          none: Nie rób niczego
+          silence: Wycisz
+          suspend: Zawieś i nieodwracalnie usuń dane konta
+        warning_preset_id: Użyj szablonu ostrzeżenia
       defaults:
         autofollow: Zapraszaj do śledzenia swojego konta
         avatar: Awatar
@@ -49,11 +69,13 @@ pl:
         context: Filtruj zawartość
         current_password: Obecne hasło
         data: Dane
+        discoverable: Wyświetlaj ten profil w katalogu
         display_name: Widoczna nazwa
         email: Adres e-mail
         expires_in: Wygaśnie po
         fields: Metadane profilu
         header: Nagłówek
+        inbox_url: Adres skrzynki przekaźnika
         irreversible: Usuwaj zamiast ukrywać
         locale: Język interfejsu
         locked: Ustaw konto jako prywatne
@@ -64,13 +86,18 @@ pl:
         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_aggregate_reblogs: Grupuj podbicia na osiach czasu
         setting_auto_play_gif: Automatycznie odtwarzaj animowane GIFy
         setting_boost_modal: Pytaj o potwierdzenie przed podbiciem
         setting_default_language: Język wpisów
         setting_default_privacy: Widoczność wpisów
         setting_default_sensitive: Zawsze oznaczaj zawartość multimedialną jako wrażliwą
         setting_delete_modal: Pytaj o potwierdzenie przed usunięciem wpisu
-        setting_display_sensitive_media: Zawsze oznaczaj zawartość multimedialną jako wrażliwą
+        setting_display_media: Wyświetlanie zawartości multimedialnej
+        setting_display_media_default: Domyślne
+        setting_display_media_hide_all: Ukryj wszystko
+        setting_display_media_show_all: Pokaż wszystko
+        setting_expand_spoilers: Zawsze rozwijaj wpisy oznaczone ostrzeżeniem o zawartości
         setting_hide_network: Ukryj swoją sieć
         setting_noindex: Nie indeksuj mojego profilu w wyszukiwarkach internetowych
         setting_reduce_motion: Ogranicz ruch w animacjach
@@ -81,6 +108,7 @@ pl:
         type: Importowane dane
         username: Nazwa użytkownika
         username_or_email: Nazwa użytkownika lub adres e-mail
+        whole_word: Całe słowo
       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
@@ -92,6 +120,7 @@ pl:
         follow_request: Powiadamiaj mnie e-mailem, gdy ktoś poprosi o pozwolenie na śledzenie mnie
         mention: Powiadamiaj mnie e-mailem, gdy ktoÅ› o mnie wspomni
         reblog: Powiadamiaj mnie e-mailem, gdy ktoś podbije mój wpis
+        report: Powiadamiaj mnie e-mailem, gdy zostanie utworzone nowe zgłoszenie
     'no': Nie
     required:
       mark: "*"
diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml
index 9b72c7a7a72aa1466f079062bf55721ead99d4c8..664c07a463ce1200b5a08b72c0ad4320be5bb34a 100644
--- a/config/locales/simple_form.pt-BR.yml
+++ b/config/locales/simple_form.pt-BR.yml
@@ -2,29 +2,40 @@
 pt-BR:
   simple_form:
     hints:
+      account_warning_preset:
+        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.
+        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:
         autofollow: Pessoas que se cadastrarem através de seu convite te seguirão automaticamente
-        avatar: PNG, GIF or JPG. Arquivos de até 2MB. Eles serão diminuídos para 400x400px
+        avatar: PNG, GIF or JPG. Arquivos de até %{size}. Eles serão diminuídos para %{dimensions}px
         bot: Essa conta executa principalmente ações automatizadas e pode não ser monitorada
         context: Um ou mais contextos onde o filtro deve ser aplicado
         digest: Enviado após um longo período de inatividade com um resumo das menções que você recebeu em sua ausência
-        display_name:
-          one: <span class="name-counter">1</span> caracter restante
-          other: <span class="name-counter">%{count}</span> caracteres restantes
+        discoverable_html: O <a href="%{path}" target="_blank">diretório</a> permite encontrar contas baseado em seus interesses e atividades. Requer pelo menos %{min_followers} seguidores
+        email: Você receberá um email de confirmação
         fields: Você pode ter até 4 itens exibidos em forma de tabela no seu perfil
-        header: PNG, GIF or JPG. Arquivos de até 2MB. Eles serão diminuídos para 700x335px
+        header: PNG, GIF or JPG. Arquivos de até %{size}. Eles serão diminuídos para %{dimensions}px
+        inbox_url: Copie a URL da página inicial do repetidor que você quer usar
         irreversible: Os toots filtrados vão desaparecer irreversivelmente, mesmo se o filtro for removido depois
         locale: O idioma das telas de usuário, e-mails e notificações push
         locked: Requer aprovação manual de seguidores
-        note:
-          one: <span class="note-counter">1</span> caracter restante
-          other: <span class="note-counter">%{count}</span> caracteres restantes
+        password: Use pelo menos 8 caracteres
         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.
+        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
       imports:
         data: Arquivo CSV exportado de outra instância do Mastodon
       sessions:
@@ -36,6 +47,18 @@ pt-BR:
         fields:
           name: Rótulo
           value: Conteúdo
+      account_warning_preset:
+        text: Texto pré-definido
+      admin_account_action:
+        send_email_notification: Notificar o usuário por e-mail
+        text: Aviso customizado
+        type: Ação
+        types:
+          disable: Desabilitar
+          none: Não fazer nada
+          silence: Silenciar
+          suspend: Suspender e excluir irreversivelmente dados da conta
+        warning_preset_id: Usar um aviso pré-definido
       defaults:
         autofollow: Convite para seguir a sua conta
         avatar: Avatar
@@ -46,11 +69,13 @@ pt-BR:
         context: Contextos de filtro
         current_password: Senha atual
         data: Dados
+        discoverable: Listar essa conta no diretório
         display_name: Nome de exibição
         email: Endereço de e-mail
         expires_in: Expira em
         fields: Metadados do perfil
         header: Cabeçalho
+        inbox_url: URL da caixa de entrada do repetidor
         irreversible: Ignorar ao invés de esconder
         locale: Idioma das telas
         locked: Trancar conta
@@ -60,13 +85,18 @@ pt-BR:
         otp_attempt: Código de autenticação em dois passos
         password: Senha
         phrase: Palavra-chave ou frase
+        setting_aggregate_reblogs: Agrupar compartilhamentos nas timelines
         setting_auto_play_gif: Reproduzir GIFs automaticamente
         setting_boost_modal: Mostrar diálogo de confirmação antes de compartilhar postagem
         setting_default_language: Idioma das postagens
         setting_default_privacy: Privacidade das postagens
         setting_default_sensitive: Sempre marcar mídia como sensível
         setting_delete_modal: Mostrar diálogo de confirmação antes de deletar uma postagem
-        setting_display_sensitive_media: Sempre exibir mídia marcada como sensível
+        setting_display_media: Exibição das mídias
+        setting_display_media_default: Padrão
+        setting_display_media_hide_all: Esconder tudo
+        setting_display_media_show_all: Mostrar tudo
+        setting_expand_spoilers: Sempre expandir toots marcados com aviso de conteúdo
         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
@@ -77,6 +107,7 @@ pt-BR:
         type: Tipo de importação
         username: Nome de usuário
         username_or_email: Nome de usuário ou e-mail
+        whole_word: Palavra inteira
       interactions:
         must_be_follower: Bloquear notificações de não-seguidores
         must_be_following: Bloquear notificações de pessoas que você não segue
@@ -88,6 +119,7 @@ pt-BR:
         follow_request: Mandar um e-maill quando alguém solicitar ser seu seguidor
         mention: Mandar um e-mail quando alguém te mencionar
         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: "*"
diff --git a/config/locales/simple_form.pt.yml b/config/locales/simple_form.pt.yml
index 5b79bd29f75277cefa516ff80d226ea577a05f51..88be3ac70fff8292db92fd1bb7c7b17c530b5d69 100644
--- a/config/locales/simple_form.pt.yml
+++ b/config/locales/simple_form.pt.yml
@@ -3,16 +3,10 @@ pt:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF or JPG. Arquivos até 2MB. Vão ser reduzidos para 400x400px
+        avatar: PNG, GIF or JPG. Arquivos até %{size}. Vão ser reduzidos para %{dimensions}px
         digest: Enviado após um longo período de inatividade e apenas se foste mencionado na tua ausência
-        display_name:
-          one: <span class="name-counter">1</span> caracter restante
-          other: <span class="name-counter">%{count}</span> caracteres restantes
-        header: PNG, GIF or JPG. Arquivos até 2MB. Vão ser reduzidos para 700x335px
+        header: PNG, GIF or JPG. Arquivos até %{size}. Vão ser reduzidos para %{dimensions}px
         locked: Requer aprovação manual de seguidores
-        note:
-          one: <span class="note-counter">1</span> caracter restante
-          other: <span class="note-counter">%{count}</span> caracteres restantes
         setting_noindex: Afecta o teu perfil público e as páginas das tuas publicações
         setting_theme: Afecta a aparência do Mastodon quando entras na tua conta em qualquer dispositivo.
       imports:
diff --git a/config/locales/simple_form.ro.yml b/config/locales/simple_form.ro.yml
new file mode 100644
index 0000000000000000000000000000000000000000..757b8720434521413af3a21ad350c88dfd60fd24
--- /dev/null
+++ b/config/locales/simple_form.ro.yml
@@ -0,0 +1,122 @@
+---
+ro:
+  simple_form:
+    hints:
+      account_warning_preset:
+        text: Poți utiliza sintaxe precum URL, hastag sau menționări
+      admin_account_action:
+        send_email_notification: Utilizatorul va primi o explicație cu privire la ceea ce sa întâmplat cu contul lui
+        text_html: Opțional. Poți utiliza sintaxe. Poți <a href="%{path}">adăuga avertismente predefinite</a> pentru a salva timp
+        type_html: Alege ce se întâmplă cu <strong>%{acct}</strong>
+        warning_preset_id: Opțional. Poți adăuga text personalizat la sfârșitul presetului
+      defaults:
+        autofollow: Persoanele care se înregistrează datorită invitației tale te vor urmări automat
+        avatar: PNG, GIF sau JPG. Cel mult %{size}. Va fi redimensionată la %{dimensions}px
+        bot: Acest cont performează în cea mai mare parte acțiuni automate și nu poate fi monitorizat
+        context: Contextele în care filtrul trebuie aplicat
+        digest: Este trimis doar după o lungă perioadă de inactivitate și numai dacă primești mesaje personale în perioada de absență
+        discoverable_html: <a href="%{path}" target="_blank">Directorul</a> permite utilizatorilor să găsească conturi după interese și activități. Necesită minim %{min_followers} urmăritori
+        email: Vei primi un e-mail de confirmare
+        fields: Poti afișa pană la maxim 4 adrese sub formă de tabel pe pofilul tău
+        header: PNG, GIF sau JPG. Cel mult %{size}. Vor fi redimensionate la %{dimensions}px
+        inbox_url: Copiază adresa URL de pe prima pagină a reului pe care vrei să îl utilizezi
+        irreversible: Postările sortate vor dispărea ireversibil, chiar dacă filtrul este ulterior șters
+        locale: Limba interfaței de utilizator, e-mailurile si notificările push
+        locked: Necesită aprobare manuală a urmăritorilor
+        password: Utilizează cel puțin 8 caractere
+        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:
+        data: Fișierul CSV exportat de la o altă instanță
+      sessions:
+        otp: 'Introdu codul pentru dubla protecție generat de telefonul mobil sau unul din codurile de rezervă:'
+      user:
+        chosen_languages: Doar postările în limbile selectate vor fi afișate în fluxurile publice
+    labels:
+      account:
+        fields:
+          name: Etichetă
+          value: Conținut
+      account_warning_preset:
+        text: Text presetat
+      admin_account_action:
+        send_email_notification: Notificați utilizatorul prin e-mail
+        text: Avertisment personalizat
+        type: Acțiune
+        types:
+          disable: Dezactivează
+          none: Nu fă nimic
+          silence: Liniște
+          suspend: Suspendă și șterge ireversibil datele contului
+        warning_preset_id: Utilizează un avertisment predefinit
+      defaults:
+        autofollow: Invită să te urmărească
+        avatar: Fotografie de profil
+        bot: Acesta este un cont automat (bot)
+        chosen_languages: Limbile filtrului
+        confirm_new_password: Confirmă noua parolă
+        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
+        expires_in: Expiră după
+        fields: Rețele externe - Unde mai poți fi găsit
+        header: Antet
+        inbox_url: Adresa URL a inbox-ului
+        irreversible: Lasă înloc să ascunzi
+        locale: Limbă
+        locked: Cont Privat
+        max_uses: Numărul maxim de utilizatori
+        new_password: Parola nouă
+        note: Descriere
+        otp_attempt: Cod dublă protecție
+        password: Parolă
+        phrase: Cuvânt sau frază
+        setting_auto_play_gif: Redă automat animațiile GIF
+        setting_boost_modal: Arată dialogul de confirmare înainte de a redistribui
+        setting_default_language: În ce limbă postezi
+        setting_default_privacy: Cine vede postările tale
+        setting_default_sensitive: Întotdeauna marchează conținutul media ca sensibil
+        setting_delete_modal: Arată dialogul de confirmare înainte de a șterge o postare
+        setting_display_media_default: Standard
+        setting_hide_network: Ascunde rețeaua
+        setting_noindex: Nu permite motoarelor de căutare să indexeze rețeaua ta
+        setting_reduce_motion: Redu mișcarea în animații
+        setting_system_font_ui: Utilizează fontul standard as sistemului
+        setting_theme: Tema siteului
+        setting_unfollow_modal: Arată dialogul de confirmare înainte de a nu mai urmări pe cineva
+        severity: Severitate
+        type: Ce importați
+        username: Nume de utilizator
+        username_or_email: Numele de utilizator sau adresa de E-mail
+        whole_word: Cuvânt întreg
+      interactions:
+        must_be_follower: Blochează notificările de la persoane care nu te urmăresc
+        must_be_following: Blochează notificările de la persoane pe care nu le urmărești
+        must_be_following_dm: Blochează mesajele directe de la persoane pe care nu le urmărești
+      notification_emails:
+        digest: Trimite rezumate
+        favourite: Trimite e-mail când cineva favorizează unul din statusurile tale
+        follow: Trimite e-mail când cineva te urmărește
+        follow_request: Trimite e-mail când cineva trimite o cerere de urmărire
+        mention: Trimite e-mail când cineva te menționează
+        reblog: Trimite e-mail când cineva redistribuie unul din statusurile tale
+        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 6bb95b13faa6422fb21ef085ab438f5195719e1b..44cd7ccd6265b145ec4d2f1a472c960cdfec1190 100644
--- a/config/locales/simple_form.ru.yml
+++ b/config/locales/simple_form.ru.yml
@@ -3,59 +3,66 @@ ru:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF или JPG. Максимально 2MB. Будет уменьшено до 400x400px
+        autofollow: Люди, пришедшие по этому приглашению автоматически будут подписаны на Вас
+        avatar: PNG, GIF или JPG. Максимально %{size}. Будет уменьшено до %{dimensions}px
         bot: Этот аккаунт обычно выполяет автоматизированные действия и может не просматриваться владельцем
+        context: Один или несколько контекстов, к которым должны быть применены фильтры
         digest: Отсылается лишь после длительной неактивности, если Вы в это время получали личные сообщения
-        display_name:
-          few: Осталось <span class="name-counter">%{count}</span> символа
-          many: Осталось <span class="name-counter">%{count}</span> символов
-          one: Остался <span class="name-counter">1</span> символ
-          other: Осталось <span class="name-counter">%{count}</span> символов
         fields: В профиле можно отобразить до 4 пунктов как таблицу
-        header: PNG, GIF или JPG. Максимально 2MB. Будет уменьшено до 700x335px
+        header: PNG, GIF или JPG. Максимально %{size}. Будет уменьшено до %{dimensions}px
+        inbox_url: Копировать URL с главной страницы ретранслятора, который Вы хотите использовать
+        irreversible: Отфильтрованные статусы будут утеряны навсегда, даже если в будущем фильтр будет убран
+        locale: Язык интерфейса, e-mail писем и push-уведомлений
         locked: Потребует от Вас ручного подтверждения подписчиков, изменит приватность постов по умолчанию на "только для подписчиков"
-        note:
-          few: Осталось <span class="name-counter">%{count}</span> символа
-          many: Осталось <span class="name-counter">%{count}</span> символов
-          one: Остался <span class="name-counter">1</span> символ
-          other: Осталось <span class="name-counter">%{count}</span> символов
+        phrase: Будет сопоставлено независимо от присутствия в тексте или предупреждения о содержании статуса
+        scopes: Какие API приложению будет позволено использовать. Если Вы выберите самый верхний, нижестоящие будут выбраны автоматически.
+        setting_default_language: Язык Ваших статусов может быть определён автоматически, но не всегда правильно
         setting_hide_network: Те, на кого Вы подписаны и кто подписан на Вас, не будут отображены в Вашем профиле
         setting_noindex: Относится к Вашему публичному профилю и страницам статусов
         setting_theme: Влияет на внешний вид Mastodon при выполненном входе в аккаунт.
+        whole_word: Если слово или фраза состоит только из букв и цифр, сопоставление произойдёт только по полному совпадению
       imports:
         data: Файл CSV, экспортированный с другого узла Mastodon
       sessions:
         otp: 'Введите код двухфакторной аутентификации, сгенерированный в мобильном приложении, или используйте один из Ваших кодов восстановления:'
+      user:
+        chosen_languages: Если выбрано, то в публичных лентах будут показаны только посты на выбранных языках
     labels:
       account:
         fields:
           name: Пункт
           value: Значение
       defaults:
+        autofollow: Пригласите подписаться на Ваш аккаунт
         avatar: Аватар
         bot: Это аккаунт бота
+        chosen_languages: Фильтр языков
         confirm_new_password: Повторите новый пароль
         confirm_password: Повторите пароль
+        context: Контекст фильтра
         current_password: Текущий пароль
         data: Данные
         display_name: Показываемое имя
         email: Адрес e-mail
-        expires_in: Срок действия
+        expires_in: Истекает через
         fields: Метаданные профиля
         header: Заголовок
-        locale: Язык
+        inbox_url: URL для входящих от ретрансляторов
+        irreversible: Удалять, а не скрывать
+        locale: Язык интерфейса
         locked: Сделать аккаунт закрытым
         max_uses: Макс. число использований
         new_password: Новый пароль
         note: О Вас
         otp_attempt: Двухфакторный код
         password: Пароль
+        phrase: Слово или фраза
         setting_auto_play_gif: Автоматически проигрывать анимированные GIF
         setting_boost_modal: Показывать диалог подтверждения перед продвижением
+        setting_default_language: Язык отправляемых статусов
         setting_default_privacy: Видимость постов
         setting_default_sensitive: Всегда отмечать медиаконтент как чувствительный
         setting_delete_modal: Показывать диалог подтверждения перед удалением
-        setting_display_sensitive_media: Всегда показывать медиаконтент, отмеченный как чувствительный
         setting_hide_network: Скрыть свои связи
         setting_noindex: Отказаться от индексации в поисковых машинах
         setting_reduce_motion: Уменьшить движение в анимации
@@ -66,6 +73,7 @@ ru:
         type: Тип импорта
         username: Имя пользователя
         username_or_email: Имя пользователя или e-mail
+        whole_word: Слово целиком
       interactions:
         must_be_follower: Заблокировать уведомления не от подписчиков
         must_be_following: Заблокировать уведомления от людей, на которых Вы не подписаны
@@ -77,6 +85,7 @@ ru:
         follow_request: Уведомлять по e-mail, когда кто-то запрашивает разрешение на подписку
         mention: Уведомлять по e-mail, когда кто-то упомянул Вас
         reblog: Уведомлять по e-mail, когда кто-то продвинул Ваш статус
+        report: Уведомлять по e-mail при создании жалобы
     'no': Нет
     required:
       mark: "*"
diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml
index 39fa3b8337682b8e26dc5562daeea058a388e965..f2d26cf026ece21e483ed7c6ff456214debe75d7 100644
--- a/config/locales/simple_form.sk.yml
+++ b/config/locales/simple_form.sk.yml
@@ -2,31 +2,40 @@
 sk:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Môžeš používať rovnakú syntaxiu ako v rámci príspevkov, čiže URL, haštagy, a spomenutia
+      admin_account_action:
+        send_email_notification: Užívateľ dostane vysvetlenie ohľadom toho, čo sa stalo s ich účtom
+        text_html: Voliteľné. Môžeš používať rovnakú syntaxiu ako v príspevkoch. Môžeš pridať <a href="%{path}">varovné predlohy</a> a ušetriť tak čas
+        type_html: Vyber si, čo urobiť s účtom <strong>%{acct}</strong>
+        warning_preset_id: Voliteľné. Stále môžeš vložiť vlastný text na samý koniec predlohy
       defaults:
         autofollow: Ľudia ktorí sa zaregistrujú prostredníctvom pozvánky, ťa budú inheď následovať
-        avatar: PNG, GIF alebo JPG. Maximálne 2MB. Bude zmenšený na 400x400px
+        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č
-        display_name:
-          few: Ostávajú ti <span class="name-counter">%{count}</span> znaky
-          one: Ostáva ti <span class="name-counter">1</span> znak
-          other: Ostáva ti <span class="name-counter">%{count}</span> znakov
-        fields: Môžeš mať 4 položky na svojom profile zobrazené vo forme tabuľky
-        header: PNG, GIF alebo JPG. Maximálne 2MB. Bude zmenšený na 700x335px
+        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
+        header: PNG, GIF, alebo JPG. Maximálne %{size}. Bude zmenšený na %{dimensions}px
+        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 manuálne schvalovať sledujúcich
-        note:
-          few: Ostávajú ti <span class="note-counter">%{count}</span> znaky
-          one: Ostáva ti <span class="note-counter">1</span> znak
-          other: Ostáva ti <span class="note-counter">%{count}</span> znakov
+        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
+        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_noindex: Ovplyvňuje verejný profil a statusy
-        setting_theme: Toto ovplyvňuje ako Mastodon vyzerá pri prihlásení z hociakého zariadenia.
+        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.
+        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
       imports:
         data: CSV súbor vyexportovaný z inej Mastodon inštancie
       sessions:
@@ -38,6 +47,18 @@ sk:
         fields:
           name: Označenie
           value: Obsah
+      account_warning_preset:
+        text: Text predlohy
+      admin_account_action:
+        send_email_notification: Oznám užívateľovi cez email
+        text: Špecifické varovanie
+        type: Úkon
+        types:
+          disable: Deaktivuj
+          none: Neurob nič
+          silence: Utíšenie
+          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
@@ -48,11 +69,13 @@ sk:
         context: Triedenie kontextov
         current_password: Súčasné heslo
         data: Dáta
+        discoverable: Zaraď tento účet do databázy
         display_name: Meno
         email: Emailová adresa
         expires_in: Expirovať po
         fields: Metadáta profilu
         header: Obrázok v hlavičke
+        inbox_url: URL adresa prechodnej schránky
         irreversible: Zahoď, namiesto skritia
         locale: Jazyk rozhrania
         locked: Zamknúť účet
@@ -62,13 +85,18 @@ sk:
         otp_attempt: Dvoj-faktorový overovací (2FA) kód
         password: Heslo
         phrase: Kľúčové slovo, alebo fráza
-        setting_auto_play_gif: Automaticky prehrávať animované GIFy
-        setting_boost_modal: Zobrazovať potvrdzovacie okno pred re-toot
+        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
         setting_default_language: Píšeš v jazyku
         setting_default_privacy: Súkromie príspevkov
         setting_default_sensitive: Označ všetky mediálne súbory ako chúlostivé
         setting_delete_modal: Zobrazuj potvrdzovacie okno pred vymazaním toot-u
-        setting_display_sensitive_media: Vždy zobrazuj médiá ktoré sú označené ako chúlostivé
+        setting_display_media: Zobrazovanie médií
+        setting_display_media_default: Å tandard
+        setting_display_media_hide_all: Skryť 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_noindex: Nezaraďuj príspevky do indexu pre vyhľadávče
         setting_reduce_motion: Redukovať pohyb v animáciách
@@ -79,17 +107,19 @@ sk:
         type: Typ importu
         username: Prezývka
         username_or_email: Prezívka, alebo email
+        whole_word: Celé slovo
       interactions:
-        must_be_follower: Blokovať oznámenia od užívateľov, ktorí ťa nesledujú
-        must_be_following: Blokovať oboznámenia ohľadom ľudí ktorých nesleduješ
-        must_be_following_dm: Blokovať súkromné správy od ľudí ktorých nesleduješ
+        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š
       notification_emails:
-        digest: Posielať súhrnné emaily
-        favourite: Poslať email ak niekto označí váš príspevok ako obľúbený
+        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
     'no': Nie
     required:
       mark: "*"
diff --git a/config/locales/simple_form.sl.yml b/config/locales/simple_form.sl.yml
index 31d1e117016dff618e637cfd278e0716852d9dc1..890cbac418fe4c0b3951f0becca3e3a8d6ccb91f 100644
--- a/config/locales/simple_form.sl.yml
+++ b/config/locales/simple_form.sl.yml
@@ -3,13 +3,102 @@ sl:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF ali JPG. Največ 2MB. Zmanjšana bo na 400x400px
-        bot: Opozarja ljudi, da račun ne predstavlja osebe
+        autofollow: Osebe, ki se prijavijo prek povabila, vas bodo samodejno sledile
+        avatar: PNG, GIF ali JPG. Največ %{size}. Zmanjšana bo na %{dimensions}px
+        bot: Ta račun v glavnem opravlja samodejna dejanja in morda ni pod nadzorom
+        context: En ali več kontekstov, kjer naj se uporabi filter
         digest: Pošlje se le po dolgem obdobju nedejavnosti in samo, če ste prejeli osebna sporočila v vaši odsotnosti
-        display_name:
-          one: <span class="name-counter">1</span> znak ostane
-          other: <span class="name-counter">%{count}</span> znakov ostane
+        email: Poslali vam bomo potrditveno e-pošto
         fields: Na svojem profilu lahko imate do 4 predmete prikazane kot tabelo.
-        header: PNG, GIF ali JPG. Največ 2MB. Zmanjšana bo na 700x335px
+        header: PNG, GIF ali JPG. Največ %{size}. Zmanjšana bo na %{dimensions}px
+        inbox_url: Kopirajte URL naslov s prve strani releja, ki ga želite uporabiti
+        irreversible: Filtrirani trobi bodo nepovratno izginili, tudi če je filter kasneje odstranjen
+        locale: Jezik uporabniškega vmesnika, e-poštnih sporočil in potisnih obvestil
+        locked: Zahteva, da ročno odobrite sledilce
+        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:
         data: Izvožena CSV datoteka iz drugega Mastodon vozlišča
+      sessions:
+        otp: 'Vnesite dvomestno kodo, ki je ustvarjena z aplikacijo na telefonu, ali uporabite eno od vaših obnovitvenih kod:'
+      user:
+        chosen_languages: Ko je označeno, bodo v javnih časovnicah prikazani samo trobi v izbranih jezikih
+    labels:
+      account:
+        fields:
+          name: Oznaka
+          value: Vsebina
+      defaults:
+        autofollow: Povabite, da sledi vašemu računu
+        avatar: Podoba
+        bot: To je račun robota
+        chosen_languages: Filtriraj jezike
+        confirm_new_password: Potrdite novo geslo
+        confirm_password: Potrdite geslo
+        context: Filtriraj vsebino
+        current_password: Trenutno geslo
+        data: Podatki
+        display_name: Prikazno ime
+        email: E-poštni naslov
+        expires_in: Preteče po
+        fields: Metapodatki profila
+        header: Glava
+        inbox_url: URL mape "Prejeto"
+        irreversible: Opusti namesto skrij
+        locale: Jezik vmesnika
+        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
+        setting_auto_play_gif: Samodejno predvajanje animiranih GIF-ov
+        setting_boost_modal: Pred sunkom pokaži potrditveno okno
+        setting_default_language: Jezik objavljanja
+        setting_default_privacy: Zasebnost objave
+        setting_default_sensitive: Vedno označi medije kot občutljive
+        setting_delete_modal: Pred brisanjem troba prikaži okno za pritrditev
+        setting_display_media: Prikaz medijev
+        setting_display_media_default: Privzeto
+        setting_display_media_hide_all: Skrij vse
+        setting_display_media_show_all: Prikaži vse
+        setting_expand_spoilers: Vedno razširi trobe, označene z opozorili o vsebini
+        setting_hide_network: Skrij svoje omrežje
+        setting_noindex: Odsotnost indeksiranja iskalnikov
+        setting_reduce_motion: Zmanjšanje premikanja v animacijah
+        setting_system_font_ui: Uporabi privzeto pisavo sistema
+        setting_theme: Tema strani
+        setting_unfollow_modal: Pokaži potrditveno okno, preden nekoga prenehamo slediti
+        severity: Strogost
+        type: Vrsta uvoza
+        username: Uporabniško ime
+        username_or_email: Uporabniško ime ali E-pošta
+        whole_word: Celotna beseda
+      interactions:
+        must_be_follower: Blokiraj obvestila nesledilcev
+        must_be_following: Blokiraj obvestila oseb, ki jim ne sledite
+        must_be_following_dm: Blokiraj neposredna sporočila oseb, ki jim ne sledite
+      notification_emails:
+        digest: Pošlji izvlečke e-pošt
+        favourite: Pošlji e-pošto, ko nekdo doda vaše stanje med priljubljene
+        follow: Pošlji e-pošto, ko vas nekdo sledi
+        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
+    'no': Ne
+    required:
+      mark: "*"
+      text: zahtevano
+    'yes': Da
diff --git a/config/locales/simple_form.sr-Latn.yml b/config/locales/simple_form.sr-Latn.yml
index 608630c0ce300d6b8b6f3f70044ddafb772864cd..eac64988fecac1502ce39ef06d22aaa3de95eec4 100644
--- a/config/locales/simple_form.sr-Latn.yml
+++ b/config/locales/simple_form.sr-Latn.yml
@@ -3,26 +3,16 @@ sr-Latn:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF ili JPG. Najviše 2MB. Biće smanjena na 400x400px
+        avatar: PNG, GIF ili JPG. Najviše %{size}. Biće smanjena na %{dimensions}px
         digest: Poslato posle dužeg perioda neaktivnosti sa pregledom svih bitnih stvari koje ste dobili dok ste bili odsutni
-        display_name:
-          few: <span class="name-counter">%{count}</span> karaktera preostala
-          many: <span class="name-counter">%{count}</span> karaktera preostalo
-          one: <span class="name-counter">1</span> karakter preostao
-          other: <span class="name-counter">%{count}</span> karaktera preostalo
-        header: PNG, GIF ili JPG. Najviše 2MB. Biće smanjena na 700x335px
+        header: PNG, GIF ili JPG. Najviše %{size}. Biće smanjena na %{dimensions}px
         locked: Zahteva da pojedinačno odobrite pratioce
-        note:
-          few: <span class="note-counter">%{count}</span> karaktera preostal
-          many: <span class="note-counter">%{count}</span> karaktera preostalo
-          one: <span class="note-counter">1</span> karakter preostao
-          other: <span class="note-counter">%{count}</span> karaktera preostalo
         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.
+        otp: 'Unesite dvofaktorski kod sa Vašeg telefona ili koristite jedan od kodova za oporavak:'
     labels:
       defaults:
         avatar: Avatar
diff --git a/config/locales/simple_form.sr.yml b/config/locales/simple_form.sr.yml
index ab9ef0f492a14e95675808988709582b9cca4799..7e3c6685e09104123352211eb28620d68b8eeb88 100644
--- a/config/locales/simple_form.sr.yml
+++ b/config/locales/simple_form.sr.yml
@@ -2,38 +2,81 @@
 sr:
   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:
-        avatar: PNG, GIF или JPG. Највише 2MB. Биће смањена на 400x400px
+        autofollow: Особе које се пријаве кроз позивнице ће вас аутоматски запратити
+        avatar: PNG, GIF или JPG. Највише %{size}. Биће смањена на %{dimensions}px
+        bot: Овај налог углавном врши аутоматизоване радње и можда се не надгледа
+        context: Један или више контекста у којима треба да се примени филтер
         digest: Послато после дужег периода неактивности са прегледом свих битних ствари које сте добили док сте били одсутни
-        display_name:
-          few: <span class="name-counter">%{count}</span> карактера преостала
-          many: <span class="name-counter">%{count}</span> карактера преостало
-          one: <span class="name-counter">1</span> карактер преостао
-          other: <span class="name-counter">%{count}</span> карактера преостало
-        header: PNG, GIF или JPG. Највише 2MB. Биће смањена на 700x335px
+        discoverable_html: <a href="%{path}" target="_blank">Директоријум</a> омогућава људима да пронађу налоге засноване на интересима и активности.  Захтева бар %{min_followers} пратиоца
+        email: Биће вам послата е-пошта са потврдом
+        fields: Можете имати до 4 ставке приказане као табела на вашем профилу
+        header: PNG, GIF или JPG. Највише %{size}. Биће смањена на %{dimensions}px
+        inbox_url: Копирајте URL са насловне стране релеја који желите користити
+        irreversible: Филтриранe трубе ће нестати неповратно, чак и ако је филтер касније уклоњен
+        locale: Језик корисничког интерфејса, е-поште и мобилних обавештења
         locked: Захтева да појединачно одобрите пратиоце
-        note:
-          few: <span class="note-counter">%{count}</span> карактера преостал
-          many: <span class="note-counter">%{count}</span> карактера преостало
-          one: <span class="note-counter">1</span> карактер преостао
-          other: <span class="note-counter">%{count}</span> карактера преостало
+        password: Користите најмање 8 знакова
+        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:
         data: CSV фајл извезен са друге Мастодонт инстанце
       sessions:
-        otp: Унесите двофакторски код са Вашег телефона или користите један од кодова за опоравак.
+        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:
+        autofollow: Позовите да прати ваш налог
         avatar: Аватар
+        bot: Ово је налог бота
+        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: Максимални број коришћења
@@ -41,11 +84,20 @@ sr:
         note: Биографија
         otp_attempt: Двофакторски код
         password: Лозинка
+        phrase: Кључна реч или фраза
+        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: Одјави се од индексирања search engine-а
         setting_reduce_motion: Смањи покрете у анимацијама
         setting_system_font_ui: Користи системски фонт
@@ -54,6 +106,8 @@ sr:
         severity: Оштрина
         type: Тип увоза
         username: Корисничко име
+        username_or_email: Корисничко име или Е-пошта
+        whole_word: Цела реч
       interactions:
         must_be_follower: Блокирај обавештења од корисника који ме не прате
         must_be_following: Блокирај обавештења од људи које не пратим
@@ -65,6 +119,7 @@ sr:
         follow_request: Шаљи е-пошту када неко затражи да Вас запрати
         mention: Шаљи е-пошту када Вас неко помене
         reblog: Шаљи е-пошту када неко подржи Ваш статус
+        report: Пошаљи Е-пошту када се поднесе нова пријава
     'no': Не
     required:
       mark: "*"
diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml
index e761f3d99728065c8ecee50da38c4b6a0beaca8d..8bc82c6093d84d306f012a6b3471973fd47a8715 100644
--- a/config/locales/simple_form.sv.yml
+++ b/config/locales/simple_form.sv.yml
@@ -4,19 +4,13 @@ sv:
     hints:
       defaults:
         autofollow: Användarkonton som skapas genom din inbjudan kommer automatiskt följa dig
-        avatar: Högst 2 MB. Kommer att skalas ner till 400x400px
+        avatar: 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
-        display_name:
-          one: <span class="name-counter">1</span> tecken kvar
-          other: <span class="name-counter">%{count}</span> tecken kvar
         fields: Du kan ha upp till 4 objekt visade som en tabell på din profil
-        header: NG, GIF eller JPG. Högst 2 MB. Kommer nedskalas till 700x335px
+        header: NG, GIF eller JPG. Högst %{size}. Kommer nedskalas till %{dimensions}px
         locale: Användargränssnittets språk, e-post och push aviseringar
         locked: Kräver att du manuellt godkänner följare
-        note:
-          one: <span class="note-counter">1</span> tecken kvar
-          other: <span class="note-counter">%{count}</span> tecken kvar
         setting_default_language: Språket av dina inlägg kan upptäckas automatiskt, men det är inte alltid rätt
         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
@@ -59,7 +53,6 @@ sv:
         setting_default_privacy: Postintegritet
         setting_default_sensitive: Markera alltid media som känsligt
         setting_delete_modal: Visa bekräftelsedialog innan du raderar en toot
-        setting_display_sensitive_media: Visa alltid media märkt som känsligt
         setting_hide_network: Göm ditt nätverk
         setting_noindex: Uteslutning av sökmotorindexering
         setting_reduce_motion: Minska rörelser i animationer
diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml
index 575b6a9f4735fd55e8001831e078ea3e7e30b00b..a8611c2f77a41a8a427e6974f105a65d04c50c17 100644
--- a/config/locales/simple_form.th.yml
+++ b/config/locales/simple_form.th.yml
@@ -3,15 +3,9 @@ th:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px
-        display_name:
-          one: <span class="name-counter">1</span> character left
-          other: <span class="name-counter">%{count}</span> characters left
-        header: PNG, GIF or JPG. At most 2MB. Will be downscaled to 700x335px
+        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
-        note:
-          one: <span class="name-counter">1</span> character left
-          other: <span class="note-counter">%{count}</span> characters left
       imports:
         data: CSV file exported from another Mastodon instance
       sessions:
diff --git a/config/locales/simple_form.tr.yml b/config/locales/simple_form.tr.yml
index c827aac4655982a6ded9a1bf2a7bdc234d14570d..d0b50609b0dfa7625a6f32af1b5cd66405d33280 100644
--- a/config/locales/simple_form.tr.yml
+++ b/config/locales/simple_form.tr.yml
@@ -3,11 +3,9 @@ tr:
   simple_form:
     hints:
       defaults:
-        avatar: En fazla 2MB olacak şekilde PNG, GIF veya JPG formatında yükleyiniz. 400x400px büyüklüğüne indirgenecektir
-        display_name: <span class="name-counter">%{count}</span> karakter kaldı
-        header: En fazla 2MB olacak şekilde PNG, GIF veya JPG formatında yükleyiniz. 700x335px büyüklüğüne indirgenecektir.
+        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.
-        note: <span class="note-counter">%{count}</span> karakter kaldı
       imports:
         data: Diğer Mastodon sunucusundan dışarı aktardığınız CSV dosyası
       sessions:
diff --git a/config/locales/simple_form.uk.yml b/config/locales/simple_form.uk.yml
index 7bc3ee4b87030acfc6e725250ffe51db5030fc15..05d57509e0bb179986e95529b09090e5e08bc27c 100644
--- a/config/locales/simple_form.uk.yml
+++ b/config/locales/simple_form.uk.yml
@@ -3,11 +3,10 @@ uk:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF, або JPG. Максимум - 2МБ. Буде зменшено до 400x400px
-        display_name: 'Залишилося символів: <span class="name-counter">%{count}</span>'
-        header: PNG, GIF, або JPG. Максимум - 2МБ. Буде зменшено до 700x335px
+        avatar: PNG, GIF, або JPG. Максимум - %{size}. Буде зменшено до %{dimensions}px
+        bot: Цей аккаунт в основному виконує автоматичні дії та може не відстежуватіся
+        header: PNG, GIF, або JPG. Максимум - %{size}. Буде зменшено до %{dimensions}px
         locked: Буде вимагати від Вас самостійного підтверждення підписників, змінить приватність постів за замовчуванням на "тільки для підписників"
-        note: 'Осталось символов: <span class="note-counter">%{count}</span>'
       imports:
         data: Файл CSV, экспортированный с другого узла Mastodon
       sessions:
diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml
index ce990d69267929ff00c9179a5c06852a35c196af..cfa6840a6a0d22601153debac327375662def064 100644
--- a/config/locales/simple_form.zh-CN.yml
+++ b/config/locales/simple_form.zh-CN.yml
@@ -4,15 +4,13 @@ zh-CN:
     hints:
       defaults:
         autofollow: 通过邀请链接注册的用户将会自动关注你
-        avatar: 文件大小限制 2MB,只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 400×400px
+        avatar: 文件大小限制 %{size},只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 %{dimensions}px
         bot: 来自这个帐户的绝大多数操作都是自动进行的,并且可能无人监控
         digest: 仅在你长时间未登录,且收到了私信时发送
-        display_name: 还能输入 <span class="name-counter">%{count}</span> 个字符
         fields: 这将会在个人资料页上以表格的形式展示,最多 4 个项目
-        header: 文件大小限制 2MB,只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 700×335px
+        header: 文件大小限制 %{size},只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 %{dimensions}px
         locale: 用户界面、电子邮件和推送通知中使用的语言
         locked: 你需要手动审核所有关注请求
-        note: 还能输入 <span class="note-counter">%{count}</span> 个字符
         setting_default_language: 嘟文语言自动检测的结果有可能不准确(此设置仅影响你的嘟文)
         setting_hide_network: 你关注的人和关注你的人将不会在你的个人资料页上展示
         setting_noindex: 此设置会影响到你的公开个人资料以及嘟文页面
@@ -55,7 +53,6 @@ zh-CN:
         setting_default_privacy: 嘟文默认可见范围
         setting_default_sensitive: 总是将我发送的媒体文件标记为敏感内容
         setting_delete_modal: 在删除嘟文前询问我
-        setting_display_sensitive_media: 总是显示标记为敏感的媒体文件
         setting_hide_network: 隐藏你的社交网络
         setting_noindex: 禁止搜索引擎建立索引
         setting_reduce_motion: 降低过渡动画效果
diff --git a/config/locales/simple_form.zh-HK.yml b/config/locales/simple_form.zh-HK.yml
index 0575c09f8c11e7b5f6d56028491448da4f952421..e28f935c2cd96cbf247003792550f3dd4e1b2209 100644
--- a/config/locales/simple_form.zh-HK.yml
+++ b/config/locales/simple_form.zh-HK.yml
@@ -4,19 +4,13 @@ zh-HK:
     hints:
       defaults:
         autofollow: 通過邀請網址註冊的用戶將會自動關注你
-        avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 2MB,會縮裁成 400x400px
+        avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px
         bot: 提醒用戶本帳號是機械人
         digest: 僅在你長時間未登錄,且收到了私信時發送
-        display_name:
-          one: 尚餘 <span class="name-counter">1</span> 個字
-          other: 尚餘 <span class="name-counter">%{count}</span> 個字
         fields: 個人資料頁可顯示多至 4 個項目
-        header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 2MB,會縮裁成 700x335px
+        header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px
         locale: 使用者介面、電郵和通知的語言
         locked: 你必須人手核准每個用戶對你的關注請求,而你的文章私隱會被預設為「只有關注你的人能看」
-        note:
-          one: 尚餘 <span class="note-counter">1</span> 個字
-          other: 尚餘 <span class="note-counter">%{count}</span> 個字
         setting_default_language: 你文章的語言會被自動偵測,但不一定完全準確
         setting_hide_network: 你關注的人和關注你的人將不會在你的個人資料頁上顯示
         setting_noindex: 此設定會影響到你的公開個人資料以及文章頁面
@@ -59,7 +53,6 @@ zh-HK:
         setting_default_privacy: 文章預設為
         setting_default_sensitive: 預設我的內容為敏感內容
         setting_delete_modal: 刪推前詢問我
-        setting_display_sensitive_media: 預設我的媒體為敏感內容
         setting_hide_network: 隱藏你的社交網絡
         setting_noindex: 阻止搜尋引擎檢索
         setting_reduce_motion: 減低動畫效果
diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml
index 6b1dbae910068579c3e1e4a5cba48412991f286b..3747fbb983f59b0b5e65253d490996608543987f 100644
--- a/config/locales/simple_form.zh-TW.yml
+++ b/config/locales/simple_form.zh-TW.yml
@@ -4,23 +4,23 @@ zh-TW:
     hints:
       defaults:
         autofollow: 通過邀請網址註冊的使用者將會自動關注你
-        avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 2MB,會縮裁成 400x400px
+        avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px
         bot: 這個帳號由程式進行自動式操作
+        context: 應該套用過濾器的一項或多項內容
         digest: 僅在你長時間未登入,並且收到了私訊時發送
-        display_name:
-          one: 尚餘 <span class="name-counter">1</span> 個字
-          other: 尚餘 <span class="name-counter">%{count}</span> 個字
         fields: 個人資訊頁至多可顯示 4 個項目
-        header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 2MB,會縮裁成 700x335px
+        header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px
+        inbox_url: 從您想要使用的中繼首頁複製 URL
+        irreversible: 已過濾的嘟文將會不可逆的消失,即便過濾器之後也一樣
         locale: 使用者介面、 E-mail 與通知的語言
         locked: 你必須手動核准每個使用者對你的關注請求,而你的貼文隱私將會被設定為「只有關注你的人能看」
-        note:
-          one: 尚餘 <span class="note-counter">1</span> 個字
-          other: 尚餘 <span class="note-counter">%{count}</span> 個字
+        phrase: 無論是嘟文的本文或是內容警告都會被過濾
+        scopes: 應用程式將會被允許存取哪些 API。若您選取了最高階的範圍,您就不需要再選取單獨的了。
         setting_default_language: 你嘟文的語言會被自動偵測,但不一定完全準確
         setting_hide_network: 你關注的人與關注你的人將不會在你的個人資料頁上顯示
         setting_noindex: 此設定會影響到你的公開個人資料與嘟文頁面
         setting_theme: 此設定會影響到你從任意設備登入 Mastodon 時的顯示樣式。
+        whole_word: 如果關鍵字或詞組僅有字母與數字,它將只會在符合整個單字的時候才會套用
       imports:
         data: 自其他站點匯出的 CSV 檔案
       sessions:
@@ -39,6 +39,7 @@ zh-TW:
         chosen_languages: 語言篩選
         confirm_new_password: 確認新密碼
         confirm_password: 確認密碼
+        context: 過濾範圍
         current_password: 目前密碼
         data: 資料
         display_name: 顯示名稱
@@ -46,6 +47,8 @@ zh-TW:
         expires_in: 失效時間
         fields: 資料
         header: 個人頁面圖片
+        inbox_url: 中繼收件匣的 URL
+        irreversible: 放棄而非隱藏
         locale: 介面語言
         locked: 將帳號轉為「私密」
         max_uses: 最大使用次數
@@ -53,13 +56,13 @@ zh-TW:
         note: 簡介
         otp_attempt: 兩階段認證碼
         password: 密碼
+        phrase: 關鍵字或片語
         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_sensitive_media: 預設我的媒體為敏感內容
         setting_hide_network: 隱藏你的社交網路
         setting_noindex: 阻止搜尋引擎收錄
         setting_reduce_motion: 減低動畫效果
@@ -70,6 +73,7 @@ zh-TW:
         type: 匯入資料類型
         username: 使用者名稱
         username_or_email: 使用者名稱或 E-mail
+        whole_word: 整個詞
       interactions:
         must_be_follower: 隱藏沒有關注你的使用者通知
         must_be_following: 隱藏你沒關注的使用者通知
@@ -81,6 +85,7 @@ zh-TW:
         follow_request: 當有使用者要求關注你時,發送 E-mail 通知
         mention: 當有使用者在嘟文提及你時,發送 E-mail 通知
         reblog: 都有使用者轉嘟你的嘟文時,發送 E-mail 通知
+        report: 當遞交新報告時傳送電子郵件
     'no': 否
     required:
       mark: "*"
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 2bc765fc5a79cda9ea74b9d7d08e54889a495bcf..209b955dcdb00b71f74be74eb80818952c5010be 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -1,59 +1,82 @@
 ---
 sk:
   about:
-    about_hashtag_html: Toto sú verejné toot príspevky otagované <strong>#%{hashtag}</strong>. Ak máš účet niekde vo fediverse, môžeš ich používať.
-    about_mastodon_html: Mastodon je sociálna sieť založená na otvorených webových protokoloch. Jej zrojový kód je otvorený a je decentralizovaná podobne ako email.
+    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_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
-    administered_by: 'Správca je:'
-    closed_registrations: Registrácie sú 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ľ.
+    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ľ.
     contact: Kontakt
-    contact_missing: Nezadané
-    contact_unavailable: Neuvedené
-    description_headline: ÄŒo je %{domain}?
-    domain_count_after: ďalším instanciám
-    domain_count_before: Pripojený k
+    contact_missing: Nezadaný
+    contact_unavailable: Neuvedený
+    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ť s nekalým používaním siete vytváraním etických možností.
+      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. Žiadna centrálna autorita.
-      not_a_product_title: Si človek, nie produkt
-      real_conversation_body: S 65535 znakmi a podporou pre varovania pri obrázkoch a videách sa môžeš vyjadriť tak ako budeš chcieť.
-      real_conversation_title: Vytvorený pre reálnu konverzáciu
+      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
     generic_description: "%{domain} je jeden server v sieti"
     hosted_on: Mastodon hostovaný na %{domain}
     learn_more: Zisti viac
     other_instances: Zoznam ďalších inštancií
+    privacy_policy: Ustanovenia o súkromí
     source_code: Zdrojový kód
-    status_count_after: príspevkov
+    status_count_after:
+      few: príspevkov
+      one: príspevok
+      other: príspevkov
     status_count_before: Ktorí napísali
-    user_count_after: užívateľov
+    terms: Podmienky užívania
+    user_count_after:
+      few: užívatelia
+      one: užívateľ
+      other: užívatelia
     user_count_before: Domov pre
     what_is_mastodon: ÄŒo je Mastodon?
   accounts:
-    follow: Sledovať
-    followers: Sledujúci
-    following: Sleduje
+    choices_html: "%{name}vé voľby:"
+    follow: Sleduj
+    followers:
+      few: Sledovatelia
+      one: Sledujúci
+      other: Sledovatelia
+    following: Sledovaní
+    joined: Pridal/a sa v %{date}
+    last_active: naposledy aktívny
+    link_verified_on: Vlastníctvo tohto odkazu bolo skontrolované %{date}
     media: Médiá
     moved_html: "%{name} účet bol presunutý na %{new_profile_link}:"
     network_hidden: Táto informácia nieje k dispozícii
     nothing_here: Nič tu nie je!
     people_followed_by: Ľudia, ktorých %{name} sleduje
     people_who_follow: Ľudia sledujúci %{name}
-    posts: Príspevky
+    pin_errors:
+      following: Musíš už následovať toho človeka, ktorého si praješ zviditeľniť
+    posts:
+      few: Príspevkov
+      one: Príspevok
+      other: Príspevkov
+    posts_tab_heading: Príspevky
     posts_with_replies: Príspevky s odpoveďami
-    remote_follow: Sleduj vzdialeného
     reserved_username: Prihlasovacie meno je rezervované
     roles:
       admin: Administrátor
       bot: Automat
       moderator: Moderátor
-    unfollow: Prestať sledovať
+    unfollow: Prestaň sledovať
   admin:
+    account_actions:
+      action: Vykonaj
+      title: Vykonaj moderovací úkon voči %{acct}
     account_moderation_notes:
       create: Zanechaj poznámku
       created_msg: Poznámka moderátora bola úspešne vytvorená!
@@ -66,99 +89,106 @@ sk:
       change_email:
         changed_msg: Email k tomuto účtu bol úspešne zmenený!
         current_email: Súčastný email
-        label: Zmeniť email
+        label: Zmeň email
         new_email: Nový email
-        submit: Zmeniť email
+        submit: Zmeň email
         title: Zmeň email pre %{username}
       confirm: Potvrdiť
       confirmed: Potvrdený
       confirming: Potvrdzujúci
+      deleted: Zmazané
       demote: Degradovať
       disable: Zablokovať
       disable_two_factor_authentication: Zakázať 2FA
       disabled: Blokovaný
       display_name: Zobraziť meno
       domain: Doména
-      edit: Upraviť
+      edit: Uprav
       email: Email
-      email_status: Stav Email
+      email_status: Stav emailu
       enable: Povoliť
       enabled: Povolený
       feed_url: URL časovej osi
       followers: Sledujúci
       followers_url: URL sledujúcich
-      follows: Sledovaní
+      follows: Sledovania
+      header: Hlavička
       inbox_url: URL prijatých správ
+      invited_by: Pozvaný/á užívateľom
       ip: IP
+      joined: Pridal/a sa
       location:
         all: Všetko
-        local: Lokálne
+        local: Miestne
         remote: Federované
         title: Lokácia
       login_status: Status prihlásenia
       media_attachments: Prílohy
       memorialize: Zmeniť na "Navždy budeme spomínať"
       moderation:
+        active: Aktívny/a
         all: Všetko
         silenced: Umlčané
-        suspended: Suspendované
+        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é
-      order:
-        alphabetic: Abecedne
-        most_recent: Podľa času
-        title: Zoradiť
       outbox_url: URL poslaných
-      perform_full_suspension: Suspendovať
+      perform_full_suspension: Zablokovať
       profile_url: URL profilu
       promote: Povýšiť
       protocol: Protokol
       public: Verejná os
       push_subscription_expires: PuSH odoberanie expiruje
-      redownload: Obnoviť avatar
+      redownload: Obnov profil
       remove_avatar: Odstrániť avatár
+      remove_header: Odstráň hlavičku
       resend_confirmation:
-        already_confirmed: Tento používateľ už bol potvrdený
-        send: Znova odoslať potvrdzovací e-mail
-        success: Potvrdený e-mail bol úspešne odoslaný!
-      reset: Reset
-      reset_password: Obnoviť heslo
+        already_confirmed: Tento užívateľ už je potvrdený
+        send: Znovu odoslať potvrdzovací email
+        success: Potvrdzujúci email bol úspešne odoslaný!
+      reset: Resetuj
+      reset_password: Obnov heslo
       resubscribe: Znovu odoberať
       role: Oprávnenia
       roles:
         admin: Administrátor
         moderator: Moderátor
         staff: ÄŒlen
-        user: Používateľ
+        user: Užívateľ
       salmon_url: Salmon adresa
       search: Hľadať
       shared_inbox_url: URL zdieľanej schránky
       show:
-        created_reports: Reportované týmto používateľom
-        report: report
-        targeted_reports: Nahlásenia pre tento účet
+        created_reports: Vytvorené hlásenia
+        targeted_reports: Nahlásenia od ostatných
       silence: Stíšiť
+      silenced: Utíšení
       statuses: Príspevky
       subscribe: Odoberať
+      suspended: Zablokovaní
       title: Účty
       unconfirmed_email: Nepotvrdený email
       undo_silenced: Zrušiť stíšenie
       undo_suspension: Zrušiť suspendáciu
-      unsubscribe: Prestať odoberať
-      username: Používateľske meno
+      unsubscribe: Prestaň odoberať
+      username: Prezývka
+      warn: Varovať
       web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name}pridelil/a hlásenie užívateľa %{target}sebe"
         change_email_user: "%{name} zmenil/a emailovú adresu užívateľa %{target}"
         confirm_user: "%{name} potvrdil e-mailovú adresu používateľa %{target}"
+        create_account_warning: "%{name} poslal/a varovanie užívateľovi %{target}"
         create_custom_emoji: "%{name} nahral nový emoji %{target}"
         create_domain_block: "%{name} zablokoval doménu %{target}"
         create_email_domain_block: "%{name} pridal e-mailovú doménu %{target} na zoznam zakázaných"
         demote_user: "%{name} degradoval používateľa %{target}"
+        destroy_custom_emoji: "%{name} zničil/a %{target} emoji"
         destroy_domain_block: "%{name} povolil doménu %{target}"
         destroy_email_domain_block: "%{name} pridal e-mailovú doménu %{target} na zoznam povolených"
         destroy_status: "%{name} zmazal status %{target}"
@@ -180,6 +210,7 @@ sk:
         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}"
+      deleted_status: "(zmazaný príspevok)"
       title: Kontrólny záznam
     custom_emojis:
       by_domain: Doména
@@ -206,8 +237,30 @@ sk:
       update_failed_msg: Nebolo možné aktualizovať toto emoji
       updated_msg: Emoji bolo úspešne aktualizované!
       upload: Nahrať
+    dashboard:
+      backlog: odložené aktivity
+      config: Nastavenia
+      feature_deletions: Vymazanie účtov
+      feature_invites: Pozvánky
+      feature_profile_directory: Katalóg profilov
+      feature_registrations: Registrácie
+      feature_relay: Federovací mostík
+      features: Vymoženosti
+      hidden_service: Federácia so skritými službami
+      open_reports: otvorené hlásenia
+      recent_users: Nedávny užívatelia
+      search: Celofrázové vyhľadávanie
+      single_user_mode: Jednouživateľské rozhranie
+      software: Softvér
+      space: Využitie miesta
+      title: Spravovacie rozhranie
+      total_users: užívateľov celkovo
+      trends: Trendy
+      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: Pridať nový
+      add_new: Pridaj nové doménové blokovanie
       created_msg: Doména je v procese blokovania
       destroyed_msg: Blokovanie domény bolo zrušené
       domain: Doména
@@ -222,46 +275,76 @@ sk:
         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
-      severities:
-        noop: Žiadne
-        silence: Stíšiť
-        suspend: Suspendovať
-      severity: Závažnosť
+      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
+      severity:
+        silence: utíšené
+        suspend: vylúčený
       show:
         affected_accounts:
           few: "%{count} účty v databáze ovplyvnených"
-          one: Jeden účet v databáze ovplyvnený
-          other: "%{count} účtov v databáze ovplyvnených"
+          one: Jeden účet v databáze bol ovplyvnený
+          other: "%{count} účtov v databáze bolo ovplyvnených"
         retroactive:
-          silence: Zrušiť stíšenie všetkých existujúcich účtov z tejto domény
-          suspend: Zrušiť suspendáciu všetkých existujúcich účtov z tejto domény
-        title: Zrušiť blokovanie domény pre %{domain}
+          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
+        title: Zruš blokovanie domény %{domain}
         undo: Vrátiť späť
-      title: Blokovanie domén
-      undo: Späť
+      undo: Odvolaj blokovanie domény
     email_domain_blocks:
-      add_new: Pridať nový
+      add_new: Pridaj nový
       created_msg: Emailová doména bola úspešne pridaná do zoznamu zakázaných
       delete: Zmazať
       destroyed_msg: Emailová doména bola úspešne vymazaná zo zoznamu zakázaných
       domain: Doména
       new:
-        create: Pridať doménu
+        create: Pridaj doménu
         title: Nový email na zablokovanie
       title: Blokované emailové adresy
+    followers:
+      back_to_account: Späť na účet
+      title: Následovatielia užívateľa %{acct}
     instances:
-      account_count: Známe účty
-      domain_name: Doména
-      reset: Resetovať
-      search: Hľadať
-      title: Známe instancie
+      delivery_available: Je v dosahu doručovania
+      known_accounts:
+        few: "%{count} známe účty"
+        one: "%{count} známy účet"
+        other: "%{count} známe účty"
+      moderation:
+        all: Všetky
+        limited: Obmedzené
+        title: Moderácia
+      title: Federácia
+      total_blocked_by_us: Nami blokované
+      total_followed_by_them: Nimi sledované
+      total_followed_by_us: Nami sledované
+      total_reported: Nahlásenia o nich
+      total_storage: Mediálne prílohy
     invites:
+      deactivate_all: Pozastaviť všetky
       filter:
         all: Všetky
         available: Dostupné
-        expired: Expirované
+        expired: Vypršalo
         title: Filtrovať
       title: Pozvánky
+    relays:
+      add_new: Pridaj novú priechodnú oporu
+      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é
+      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ť
+      setup: Nastav prepojenie s mostom
+      status: Stav
+      title: Mosty
     report_notes:
       created_msg: Poznámka o nahlásení úspešne vytvorená!
       destroyed_msg: Poznámka o nahlásení úspešne vymazaná!
@@ -276,7 +359,6 @@ sk:
       comment:
         none: Žiadne
       created_at: Nahlásené
-      id: Identifikácia
       mark_as_resolved: Označiť ako vyriešené
       mark_as_unresolved: Označ ako nevyriešené
       notes:
@@ -286,21 +368,16 @@ sk:
         delete: Vymaž
         placeholder: Opíš aké opatrenia boli urobené, alebo akékoľvek iné súvisiace aktualizácie…
       reopen: Znovu otvor report
-      report: Nahlásiť
-      report_contents: Obsah
+      report: 'Nahlásiť #%{id}'
       reported_account: Nahlásený účet
       reported_by: Nahlásené užívateľom
       resolved: Vyriešené
       resolved_msg: Hlásenie úspešne vyriešené!
-      silence_account: Zamĺčať účet
       status: Stav
-      suspend_account: Pozastaviť účet
-      target: Cieľ
       title: Reporty
       unassign: Odobrať
       unresolved: Nevyriešené
       updated_at: Aktualizované
-      view: Zobraziť
     settings:
       activity_api_enabled:
         desc_html: Sčítanie lokálne publikovaných príspevkov, aktívnych užívateľov, a nových registrácii, v týždenných intervaloch
@@ -311,15 +388,24 @@ sk:
       contact_information:
         email: Pracovný e-mail
         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
         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
+        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í
       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
         title: Ukazuj aj chúlostivé médiá v náhľadoch OpenGraph
+      profile_directory:
+        desc_html: Povoliť užívateľom aby boli 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
@@ -334,17 +420,20 @@ sk:
           desc_html: Povoliť každému aby si mohli vytvoriť účet
           title: Verejná registrácia
       show_known_fediverse_at_about_page:
-        desc_html: Pokiaľ je zapnuté, bude v ukážke osi možné nahliadnúť toot statusy z celého známeho fediversa. V opačnom prípade tam budú ukázané iba statusy z lokálnej osi.
-        title: Ukázať celé známe fediversum ako ukážku osi
+        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.
+        title: Ukáž celé známe fediverse na náhľade osi
       show_staff_badge:
-        desc_html: Zobraziť moderátorsku značku na užívateľovej stránke
-        title: Zobraziť značku moderátora
+        desc_html: Zobraz moderátorsky odznak na užívateľovom profile
+        title: Zobraz značku moderátora
       site_description:
-        desc_html: Oboznamujúci paragraf na hlavnej stránke a pri meta tagoch. Môžete použiť HTML kód, presnejšie  <code>&lt; a&gt;</code> a <code>&lt; em&gt; </code>.
+        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
       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
         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
       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
         title: Vlastné pravidlá prevádzky
@@ -360,13 +449,14 @@ sk:
       back_to_account: Späť na účet
       batch:
         delete: Vymazať
-        nsfw_off: Obsah nieje chúlostivý
-        nsfw_on: Označ obeah aka chúlostivý
+        nsfw_off: Označ ako nechúlostivé
+        nsfw_on: Označ ako chúlostivé
       failed_to_execute: Nepodarilo sa vykonať
       media:
         title: Médiá
       no_media: Žiadné médiá
-      title: Statusy na účte
+      no_status_selected: Žiadne príspevky neboli zmenené, keďže si žiadne nemal/a zvolené
+      title: Príspevky na účte
       with_media: S médiami
     subscriptions:
       callback_url: Zdrojová adresa URL
@@ -375,12 +465,26 @@ sk:
       last_delivery: Posledné doručenie
       title: WebSub
       topic: Téma
-    title: Administrácia
+    tags:
+      accounts: Účty
+      hidden: Skryté
+      hide: Ukri od databázy
+      name: Haštag
+      title: Haštagy
+      unhide: Ukáž v databázi
+      visible: Viditeľné
+    title: Spravovanie
+    warning_presets:
+      add_new: Pridaj nové
+      delete: Vymaž
+      edit: Uprav
+      edit_preset: Uprav varovnú predlohu
+      title: Spravuj varovné predlohy
   admin_mailer:
     new_report:
-      body: "%{reporter} nahlásil %{target}"
-      body_remote: Niekto z %{domain} nahlásil %{target}
-      subject: Nový report pre %{instance} (#%{id})
+      body: "%{reporter} nahlásil/a %{target}"
+      body_remote: Niekto z %{domain} nahlásil/a %{target}
+      subject: Nové hlásenie pre %{instance} (#%{id})
   application_mailer:
     notification_preferences: Zmeniť e-mailové voľby
     salutation: "%{name},"
@@ -397,7 +501,7 @@ sk:
     warning: Na tieto údaje dávajte ohromný pozor. Nikdy ich s nikým nezďieľajte!
     your_token: Váš 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 servisnými podmienkami </a>.
+    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>.
     change_password: Heslo
     confirm_email: Potvrdiť email
     delete_account: Vymazať účet
@@ -423,11 +527,11 @@ sk:
   authorize_follow:
     already_following: Tento účet už následuješ
     error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu
-    follow: Následovať
-    follow_request: 'Poslali ste požiadavku následovať užívateľa:'
-    following: 'Podarilo sa! Teraz už následujete užívateľa:'
+    follow: Následuj
+    follow_request: 'Poslal/a si žiadosť následovať užívateľa:'
+    following: 'Podarilo sa! Teraz už následuješ užívateľa:'
     post_follow:
-      close: Alebo môžete iba zatvoriť toto okno.
+      close: Alebo môžeš iba zatvoriť toto okno.
       return: Ukáž užívateľov profil
       web: Prejdi do siete
     title: Následuj %{acct}
@@ -449,12 +553,23 @@ sk:
     bad_password_msg: Dobrý pokus, hakeri! Nesprávne heslo
     confirm_password: Napíšte svoje terajšie heslo pre overenie vašej identity
     description_html: Týmto <strong> natrvalo, nenavrátiteľne </strong> vymažeš obsah tvojho účtu, a deaktivuješ ho. Tvoja prezývka ale ostane rezervovaná ako prevencia pred budúcimi impersonáciami.
-    proceed: Vymazať účet
-    success_msg: Váš účet bol úspešne vymazaný
-    warning_html: Iba vymazanie obsahu z tejto konkrétnej instancie je garantované. Obsah ktorý bol zdieľaný široko-ďaleko pravdepodobne zanechá nejaké stopy. Servery ktoré sú offline a tie ktoré ignorujú tvoje zmeny teda nezaktualizujú svoje databázy.
-    warning_title: O dostupnosti distribuovaného obsahu
+    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_title: Dostupnosť rozšírovaného obsahu
+  directories:
+    directory: Katalóg profilov
+    enabled: Momentálne si uvedený/á na zozname profilov.
+    enabled_but_waiting: Vyjadril/a si záujem o uvedenie na zozname profilov, lenže ešte nemáš minimálny vyžadovaný počet následovateľov (%{min_followers}), aby si tam bol/a uveden/á.
+    explanation: Pátraj po užívateľoch podľa ich záujmov
+    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"
+      one: "%{count} človek"
+      other: "%{count} ľudia"
   errors:
-    '403': Nemáte dostatočné povolenie na zobrazenie tejto stránky.
+    '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.
     '422':
@@ -464,7 +579,7 @@ sk:
     '500':
       content: Ospravedlňujeme sa. Niečo sa pokazilo na našom konci.
       title: Táto stránka nieje v poriadku
-    noscript_html: Aby bolo možné používať Mastodon web aplikáciu, prosím povoľte JavaScript. Alebo skúste jednu z <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md"> aplikácii </a> dostupných pre vašu platformu.
+    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.
   exports:
     archive_takeout:
       date: Dátum
@@ -475,7 +590,9 @@ sk:
       size: Veľkosť
     blocks: Blokujete
     csv: CSV
+    domain_blocks: Blokované domény
     follows: Následujete
+    lists: Zoznamy
     mutes: Stíšil/a si
     storage: Úložisko médií
   filters:
@@ -507,17 +624,21 @@ sk:
     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:
     changes_saved_msg: Zmeny boli úspešne uložené!
-    powered_by: poháňané vďaka %{link}
-    save_changes: Uložiť zmeny
+    copy: Kopírovať
+    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 chybu
-      other: Niečo ešte stále nieje v poriadku! Prosím skontroluj všetkých %{count} chýb
+      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
   imports:
-    preface: Môžeš importovať dáta ktoré si exportoval/a z iného Mastodon serveru, ako sú napríklad zoznamy ľudí ktorých sleduješ, alebo blokuješ.
-    success: Tvoje dáta boli nahraté úspešne, a budú teraz spracované v danom čase
+    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
       following: Zoznam sledovaných
@@ -547,8 +668,6 @@ sk:
       expires_at: Vyprší
       uses: Používa
     title: Pozvi ľudí
-  landing_strip_html: "<strong>%{name}</strong> je užívateľ na serveri %{link_to_root_path}. Ty ich môžeš následovať a môžeš s nimi interaktovať pokiaľ máš účet kdekoľvek v rámci fediversa."
-  landing_strip_signup_html: Pokiaľ ešte nemáš, môžeš <a href="%{sign_up_path}">si tu vytvoriť účet</a>.
   lists:
     errors:
       limit: Dosiahli ste maximálny možný počet zoznamov
@@ -626,50 +745,77 @@ sk:
     no_account_html: Nemáš ešte úč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."
+  remote_interaction:
+    favourite:
+      proceed: Pokračuj k obľúbeniu
+      prompt: 'Chceš si obľúbiť tento príspevok:'
+    reblog:
+      proceed: Pokračuj k vyzdvihnutiu
+      prompt: 'Chceš vyzdvihnúť tento príspevok:'
+    reply:
+      proceed: Pokračuj odpovedaním
+      prompt: 'Chceš odpovedať na tento príspevok:'
   remote_unfollow:
     error: Chyba
     title: Názov
     unfollowed: Už nesleduješ
+  scheduled_statuses:
+    over_daily_limit: Prekročil/a si denný limit %{limit} predplánovaných príspevkov
+    over_total_limit: Prekročil/a si limit %{limit} predplánovaných príspevkov
+    too_soon: Dátum musí byť stanovený do budúcnosti
   sessions:
     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óna
+    title: Sezóny
   settings:
-    authorized_apps: Autorizované aplikácie
+    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í sledovatelia
+    followers: Povolení následovatelia
     import: Importovať
     migrate: Presunúť účet
-    notifications: Oznámenia
+    notifications: Oboznámenia
     preferences: Voľby
     settings: Nastavenia
     two_factor_authentication: Dvoj-faktorové overenie
@@ -688,17 +834,20 @@ sk:
     boosted_from_html: Povýšené od %{acct_link}
     content_warning: 'Varovanie o obsahu: %{warning}'
     disallowed_hashtags:
-      one: 'obsahuje nepovolený haštag: %{tags}'
-      other: 'obsahuje nepovolené haštagy: %{tags}'
-    language_detection: Zisti jazyk automaticky
-    open_in_web: Otvor v okne prehliadača
-    over_character_limit: limit počtu %{max} znakov bol presiahnutý
+      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ý
     pin_errors:
-      limit: Už ste si pripli ten najvyšší možný počet príspevkov
-      ownership: Nemožno pripnúť príspevok od niekoho iného
+      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úť
     show_more: Ukáž viac
+    sign_in_to_participate: Prihlás sa pre zapojenie do diskusie
+    title: '%{name}: „%{quote}"'
     visibilities:
       private: Iba pre sledovateľov
       private_long: Ukáž iba následovateľom
@@ -707,12 +856,30 @@ sk:
       unlisted: Nezaradené
       unlisted_long: Všetci môžu vidieť, ale nieje zaradené do verejnej osi
   stream_entries:
-    click_to_show: Klikni pre zobrazenie
     pinned: Pripnutý toot
     reblogged: vyzdvihnutý
     sensitive_content: Senzitívny obsah
   terms:
-    title: Podmienky užívania, a pravidlá o súkromí pre %{instance}
+    body_html: |
+      <h2>Podmienky súkromia</h2>
+
+      <h3 id="collect">Aké informácie zbierame?</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é.
+      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>
+
+       <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">
+    title: Podmienky užívania, a pravidlá súkromia pre %{instance}
   themes:
     contrast: Vysoký kontrast
     default: Mastodon
@@ -720,6 +887,7 @@ sk:
   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ť.
@@ -741,6 +909,22 @@ sk:
       explanation: Vyžiadal/a si si úplnú zálohu svojho Mastodon účtu. Táto záloha je teraz pripravená na stiahnutie!
       subject: Tvoj archív je pripravený na stiahnutie
       title: Odber archívu
+    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.
+        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:
+        disable: Tvoj účet %{acct} bol zamrazený
+        none: Varovanie pre %{acct}
+        silence: Tvoj účet %{acct} bol obmedzený
+        suspend: Tvoj účet %{acct} bol vylúčený
+      title:
+        disable: Účet bol zamrazený
+        none: Varovanie
+        silence: Účet bol obmedzený
+        suspend: Tvoj účet bol vylúčený
     welcome:
       edit_profile_action: Nastav profil
       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.
@@ -752,16 +936,19 @@ sk:
       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
-      tip_bridge_html: Ak prichádzaš z Twitteru, môžeš svojích priateľov nájsť na Mastodone pomocou tzv. <a href="%{bridge_url}">mostíkovej aplikácie</a>. Ale tá funguje iba ak ju aj oni niekedy použili!
       tip_federated_timeline: Federovaná os zobrazuje sieť Mastodonu až po jej hranice. Ale zahŕňa iba ľúdí ktorých ostatní okolo teba sledujú, takže predsa nieje úplne celistvá.
       tip_following: Správcu servera následuješ automaticky. Môžeš ale nájsť mnoho iných zaujímavých ľudí ak prezrieš tak lokálnu, ako aj globálne federovanú os.
-      tip_local_timeline: Lokálna os je celkový pohľad na aktivitu užívateľov %{instance}. Toto sú tvoji najbližší susedia!
+      tip_local_timeline: Miestna časová os je celkový pohľad na aktivitu užívateľov %{instance}. Toto sú tvoji najbližší susedia!
       tip_mobile_webapp: Pokiaľ ti prehliadač ponúkne možnosť pridať Mastodon na tvoju obrazovku, môžeš potom dostávať notifikácie skoro ako z natívnej aplikácie!
       tips: Tipy
       title: Vitaj na palube, %{name}!
   users:
+    follow_limit_reached: Nemôžeš následovať viac ako %{limit} ľudí
     invalid_email: Emailová adresa je neplatná
     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:'
+  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:'
+    verification: Overenie
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index 6f581f838f560c3ae3fb856680d39c61a7684e70..594c58acc1e73106d034de9d320bb9e98a27eca7 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -5,44 +5,71 @@ 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
-    description_headline: Kaj je %{domain}?
-    domain_count_after: ostala vozlišča
-    domain_count_before: Povezan z
+    documentation: Dokumentacija
     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: statusi
+    status_count_after:
+      few: stanja
+      one: stanje
+      other: stanja
+      two: stanja
     status_count_before: Kdo je avtor
-    user_count_after: uporabniki
+    terms: Pogoji storitve
+    user_count_after:
+      few: uporabniki
+      one: uporabnik
+      other: uporabniki
+      two: uporabniki
     user_count_before: Dom za
     what_is_mastodon: Kaj je Mastodon?
   accounts:
+    choices_html: "%{name} izbire:"
     follow: Sledi
-    followers: Sledilci
+    followers:
+      few: Sledilci
+      one: Sledilec
+      other: Sledilci
+      two: Sledilci
     following: Sledim
+    joined: Se je pridružil na %{date}
+    link_verified_on: Lastništvo te povezave je bilo preverjeno na %{date}
     media: Medij
     moved_html: "%{name} se je prestavil na %{new_profile_link}:"
     network_hidden: Te informacije niso na voljo
     nothing_here: Nič ni tukaj!
     people_followed_by: Ljudje, ki jim sledi %{name}
     people_who_follow: Ljudje, ki sledijo %{name}
-    posts: Tuti
+    pin_errors:
+      following: Verjetno že sledite osebi, ki jo želite potrditi
+    posts:
+      few: Trob
+      one: Trob
+      other: Trob
+      two: Trob
+    posts_tab_heading: Trobi
     posts_with_replies: Tuti in odgovori
-    remote_follow: Oddaljeno sledenje
     reserved_username: Uporabniško ime je zasedeno
     roles:
       admin: Skrbnik
@@ -54,6 +81,7 @@ sl:
       create: Pusti sporočilo
       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
@@ -68,9 +96,11 @@ sl:
       confirm: Potrdi
       confirmed: Potrjeno
       confirming: Potrjujem
+      demote: Ponižaj
       disable: Onemogoči
       disable_two_factor_authentication: Onemogoči 2FA
       disabled: Onemogočeno
+      display_name: Prikazno ime
       domain: Domena
       edit: Uredi
       email: E-pošta
@@ -99,8 +129,10 @@ sl:
       moderation_notes: Opombe moderiranja
       most_recent_activity: Zadnja aktivnost
       most_recent_ip: Zadnji IP
-      order:
-        alphabetic: Po abecedi
-        most_recent: Najnovejše
-        title: Red
       promote: Spodbujanje
+  statuses:
+    pin_errors:
+      ownership: Trob nekoga drugega ne more biti pripet
+      private: Nejavnega troba ni mogoče pripeti
+  stream_entries:
+    pinned: Pripet trob
diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml
index b371edcafdd006de1a1b548f0167160c41b6f356..6d71b326ed5d33baf7608008c8ad5ea0db4da60a 100644
--- a/config/locales/sr-Latn.yml
+++ b/config/locales/sr-Latn.yml
@@ -8,9 +8,6 @@ sr-Latn:
     contact: Kontakt
     contact_missing: Nije postavljeno
     contact_unavailable: N/A
-    description_headline: Å ta je %{domain}?
-    domain_count_after: ostale instance
-    domain_count_before: Povezan na
     extended_description_html: |
       <h3>Dobro mesto za pravila</h3>
       <p>Prošireni opis koji još nije postavljen.</p>
@@ -44,7 +41,6 @@ sr-Latn:
     people_who_follow: Ljudi koji prate %{name}
     posts: Tutovi
     posts_with_replies: Tutovi i odgovori
-    remote_follow: Udaljena praćenja
     reserved_username: Korisničko ime je rezervisano
     roles:
       admin: Administrator
@@ -96,10 +92,6 @@ sr-Latn:
       most_recent_activity: Najskorija aktivnost
       most_recent_ip: Najskorija IP adresa
       not_subscribed: Nije pretplaćen
-      order:
-        alphabetic: Abecedni
-        most_recent: Najskoriji
-        title: Redosled
       outbox_url: Odlazno sanduče
       perform_full_suspension: Izvrši kompletno isključenje
       profile_url: Adresa profila
@@ -126,7 +118,6 @@ sr-Latn:
       shared_inbox_url: Adresa deljenog sandučeta
       show:
         created_reports: Prijave koje je napravio ovaj nalog
-        report: prijava
         targeted_reports: Prijave napravljene o ovom nalogu
       silence: Ućutkaj
       statuses: Statusi
@@ -203,12 +194,7 @@ sr-Latn:
           suspend: Suspenzija
         title: Novo blokiranje domena
       reject_media: Odbaci multimediju
-      reject_media_hint: Uklanja lokalno uskladištene multimedijske fajlove i odbija da ih skida na dalje. Nebitno je za suspenziju.
-      severities:
-        noop: Ništa
-        silence: Ućutkavanje
-        suspend: Suspenzija
-      severity: Oštrina
+      reject_media_hint: Uklanja lokalno uskladištene multimedijske fajlove i odbija da ih skida na dalje. Nebitno je za suspenziju
       show:
         affected_accounts:
           few: Utiče na %{count} naloga u bazi
@@ -220,7 +206,6 @@ sr-Latn:
           suspend: Ugasi suspenzije za sve postojeće naloge sa ovog domena
         title: Poništi blokadu domena za domen %{domain}
         undo: Poništi
-      title: Blokade domena
       undo: Poništi
     email_domain_blocks:
       add_new: Dodaj novuAdd new
@@ -233,10 +218,6 @@ sr-Latn:
         title: Nova stavka u crnoj listi e-pošti
       title: Crna lista adresa e-pošte
     instances:
-      account_count: Poznati nalozi
-      domain_name: Domen
-      reset: Resetuj
-      search: Pretraga
       title: Poznate instance
     invites:
       filter:
@@ -250,20 +231,14 @@ sr-Latn:
       are_you_sure: Da li ste sigurni?
       comment:
         none: Ništa
-      id: ID
       mark_as_resolved: Označi kao rešen
       report: 'Prijava #%{id}'
-      report_contents: Sadržaj
       reported_account: Prijavljeni nalog
       reported_by: Prijavio
       resolved: Rešeni
-      silence_account: Ućutkaj nalog
       status: Status
-      suspend_account: Suspenduj nalog
-      target: Cilj
       title: Prijave
       unresolved: Nerešeni
-      view: Pogledaj
     settings:
       bootstrap_timeline_accounts:
         desc_html: Odvojite više korisničkih imena zarezom. Radi samo za lokalne i otključane naloge. Ako je prazno, onda se odnosi na sve lokalne administratore.
@@ -399,7 +374,7 @@ sr-Latn:
     '500':
       content: Izvinjavamo se, nešto je pošlo po zlu sa ove strane.
       title: Strana nije ispravna
-    noscript_html: Da biste koristili Mastodont veb aplikaciju, omogućite JavaScript. U suprotnom, probajte neku od <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">originalnih aplikacija</a> za Mastodont za Vašu platformu.
+    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
@@ -422,7 +397,6 @@ sr-Latn:
     unlocked_warning_title: Vaš nalog nije zaključan
   generic:
     changes_saved_msg: Izmene uspešno sačuvane!
-    powered_by: omogućio %{link}
     save_changes: Snimi izmene
     validation_errors:
       few: Nešto nije baš kako treba! Pregledajte %{count} greške ispod
@@ -460,8 +434,6 @@ sr-Latn:
       expires_at: Ističe
       uses: Korišćenja
     title: Pozovi ljude
-  landing_strip_html: "<strong>%{name}</strong> je korisnik na %{link_to_root_path}. Možete ga zapratiti ili komunicirati sa njim ako imte nalog bilo gde u fediversu."
-  landing_strip_signup_html: Ako nemate, možete se <a href="%{sign_up_path}">registrovati ovde</a>.
   lists:
     errors:
       limit: Dostigli ste limit broja listi
@@ -478,7 +450,7 @@ sr-Latn:
     title: Moderacija
   notification_mailer:
     digest:
-      body: 'Evo kratak pregled šta ste propustili na instanci %{instance} od poslednje posete od %{since}:'
+      body: Evo kratak pregled šta ste propustili od poslednje posete od %{since}
       mention: "%{name} Vas je pomenuo u:"
       new_followers_summary:
         few: Dobili ste %{count} nova pratioca! Sjajno!
@@ -602,7 +574,6 @@ sr-Latn:
       unlisted: Neizlistano
       unlisted_long: Svako može da vidi, ali nije izlistano na javnim lajnama
   stream_entries:
-    click_to_show: Klikni da vidiš
     pinned: Prikačeni tut
     reblogged: podržano
     sensitive_content: Osetljiv sadržaj
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index a704bcb9af30865e75637be89bbbd3f0d309d7df..6131ed01f26035cc3068a500a40d377a7933e608 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -2,16 +2,16 @@
 sr:
   about:
     about_hashtag_html: Ово су јавни статуси таговани са <strong>#%{hashtag}</strong>. Можете одговарати на њих ако имате налог било где у федиверсу.
-    about_mastodon_html: Мастодонт је друштвена мрежа базирана на отвореним протоколима и слободном софтверу отвореног кода. Децентрализована је као што је децентрализована е-пошта.
+    about_mastodon_html: Мастодон је друштвена мрежа базирана на отвореним протоколима и слободном софтверу отвореног кода. Децентрализована је као што је децентрализована е-пошта.
     about_this: О инстанци
     administered_by: 'Администрирано од стране:'
-    closed_registrations: Регистрације су тренутно затворене на овој инстанци. Ипак! Можете наћи другу инстанцу на којој ћете направити налог и одатле добити приступ истој овој мрежи.
+    api: API
+    apps: Мобилне апликације
+    closed_registrations: Регистрације су тренутно затворене на овој инстанци. Међутим! Можете наћи другу инстанцу на којој ћете направити налог и одатле добити приступ на истој овој мрежи.
     contact: Контакт
     contact_missing: Није постављено
     contact_unavailable: N/A
-    description_headline: Шта је %{domain}?
-    domain_count_after: остале инстанце
-    domain_count_before: Повезан на
+    documentation: Документација
     extended_description_html: |
       <h3>Добро место за правила</h3>
       <p>Проширени опис који још није постављен.</p>
@@ -28,41 +28,79 @@ sr:
     hosted_on: Мастодонт хостован на %{domain}
     learn_more: Сазнајте више
     other_instances: Листа инстанци
+    privacy_policy: Полиса приватности
     source_code: Изворни код
-    status_count_after: статуса
+    status_count_after:
+      few: статуси
+      many: статуси
+      one: статус
+      other: статуси
     status_count_before: Који су написали
-    user_count_after: корисника
+    terms: Услови коришћења
+    user_count_after:
+      few: корисници
+      many: корисници
+      one: корисник
+      other: корисници
     user_count_before: Дом за
-    what_is_mastodon: Шта је Мастодонт?
+    what_is_mastodon: Шта је Мастодон?
   accounts:
-    follow: Follow
-    followers: Followers
-    following: Following
-    media: Мултимедија
-    moved_html: "%{name} је померен на %{new_profile_link}:"
+    choices_html: "%{name}'s избори:"
+    follow: Запрати
+    followers:
+      few: Пратиоци
+      many: Пратиоци
+      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}
-    posts: Тутови
-    posts_with_replies: Тутови и одговори
-    remote_follow: Удаљена праћења
+    pin_errors:
+      following: Морате пратити ову особу ако хоћете да потврдите
+    posts:
+      few: Трубе
+      many: Трубе
+      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: Направи
+      create: Оставите белешку
       created_msg: Модераторска белешка успешно направљена!
       delete: Обриши
       destroyed_msg: Модераторска белешка успешно обрисана!
     accounts:
       are_you_sure: Да ли сте сигурни?
+      avatar: Аватар
       by_domain: Домен
+      change_email:
+        changed_msg: Е-пошта налога успешно промењена!
+        current_email: Тренутна е-пошта
+        label: Промените е-пошту
+        new_email: Нова e-пошта
+        submit: Промените e-пошту
+        title: Промените e-пошту за %{username}
       confirm: Потврди
       confirmed: Потврђено
       confirming: Потврдување
+      deleted: Избрисано
       demote: Ражалуј
       disable: Искључи
       disable_two_factor_authentication: Искључи 2FA
@@ -71,15 +109,18 @@ sr:
       domain: Домен
       edit: Измени
       email: Е-пошта
-      email_status: Е-пошта статус
-      enable: Укључи
+      email_status: Статус е-поште
+      enable: Омогући
       enabled: Укључено
       feed_url: Адреса довода
       followers: Пратиоци
       followers_url: Адреса пратиоца
       follows: Праћени
+      header: Заглавље
       inbox_url: Адреса сандучета
+      invited_by: Позван од стране
       ip: IP
+      joined: Придружио се
       location:
         all: Све
         local: Локалне
@@ -89,6 +130,7 @@ sr:
       media_attachments: Мултимедијални прилози
       memorialize: Пребаци у in memoriam
       moderation:
+        active: Активан
         all: Сви
         silenced: Ућуткани
         suspended: Суспендовани
@@ -96,19 +138,18 @@ sr:
       moderation_notes: Модераторске белешке
       most_recent_activity: Најскорија активност
       most_recent_ip: Најскорија IP адреса
+      no_limits_imposed: Нема ограничења
       not_subscribed: Није претплаћен
-      order:
-        alphabetic: Абецедни
-        most_recent: Најскорији
-        title: Редослед
       outbox_url: Одлазно сандуче
-      perform_full_suspension: Изврши комплетно искључење
+      perform_full_suspension: Искључи
       profile_url: Адреса профила
       promote: Унапреди
       protocol: Протокол
       public: Јавно
-      push_subscription_expires: PuSH subscription expires
-      redownload: Освежи аватар
+      push_subscription_expires: PuSH претплата истиче
+      redownload: Освежи профил
+      remove_avatar: Уклони аватар
+      remove_header: Одстрани заглавље
       resend_confirmation:
         already_confirmed: Овој корисник е веќе потврден
         send: Препрати го е-мајлот за потврда
@@ -126,25 +167,32 @@ sr:
       search: Претрага
       shared_inbox_url: Адреса дељеног сандучета
       show:
-        created_reports: Пријаве које је направио овај налог
-        report: пријава
-        targeted_reports: Пријаве направљене о овом налогу
+        created_reports: Направљени извештаји
+        targeted_reports: Пријаве од стране других
       silence: Ућуткај
+      silenced: Ућуткан
       statuses: Статуси
       subscribe: Претплати се
+      suspended: Суспендовани
       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_custom_emoji: "%{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}"
@@ -155,42 +203,68 @@ sr:
         enable_user: "%{name} је омогућио пријављивање за корисника %{target}"
         memorialize_account: "%{name} је претворио страну налога %{target} као in memoriam страну"
         promote_user: "%{name} је унапредио корисника %{target}"
+        remove_avatar_user: "%{name} је уклонио/ла %{target}'s аватар"
+        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: Успешно направљена локална копија емотикона
+      copied_msg: Успешно направљена локална копија емоџија
       copy: Копирај
-      copy_failed_msg: Не могу да направим локалну копију тог емотикона
-      created_msg: Емотикон успешно направљен!
+      copy_failed_msg: Не могу да направим локалну копију тог емотиџија
+      created_msg: Емоџи успешно направљен!
       delete: Обриши
-      destroyed_msg: Емотикон успешно обрисан!
+      destroyed_msg: Емоџи успешно обрисан!
       disable: Онемогући
-      disabled_msg: Емотикон успешно онемогућен
-      emoji: Емотикон
+      disabled_msg: Емоџи успешно онемогућен
+      emoji: Емоџи
       enable: Омогући
-      enabled_msg: Емотикон успешно омогућен
+      enabled_msg: Емоџи успешно омогућен
       image_hint: PNG до 50KB
       listed: Излистан
       new:
-        title: Додај нови произвољни емотикон
+        title: Додај нови произвољни емоџи
       overwrite: Препиши
       shortcode: Пречица
       shortcode_hint: Најмање 2 карактера, дозвољени су само слова, бројеви и доње црте
-      title: Произвољни емотикони
+      title: Произвољни емотиџији
       unlisted: Неизлистан
-      update_failed_msg: Не могу да ажурирам овај емотикон
-      updated_msg: емотикон успешно ажуриран!
+      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: Додај нови
+      add_new: Додај нови блок домена
       created_msg: Блокирање домена се обрађује
       destroyed_msg: Блокирање домена је опозвано
       domain: Домен
@@ -198,80 +272,145 @@ sr:
         create: Направи блокаду
         hint: Блокирање домена неће спречити прављење налога у бази, али ће ретроактивно и аутоматски применити одређене модераторске методе над тим налозима.
         severity:
-          desc_html: "<strong>Ућуткавање</strong> ће све статусе овог налога учинити невидиљивим за све, осим за оне који налог већ прате. <strong>Суспензија</strong> ће уклонити сав садржај налога, сву мултимедију, и профилне податке. Користите <strong>Ништа</strong> ако само желите да одбаците мултимедијалне фајлове."
+          desc_html: "<strong>Ућуткавање</strong> ће све статусе овог налога учинити невидљивим за све, осим за оне који већ прате налог. <strong>Суспензија</strong> ће уклонити сав садржај налога, сву мултимедију, и профилне податке. Користите <strong>Ништа</strong> само ако желите да одбаците мултимедијалне фајлове."
           noop: Ништа
           silence: Ућуткавање
           suspend: Суспензија
         title: Ново блокирање домена
       reject_media: Одбаци мултимедију
-      reject_media_hint: Уклања локално ускладиштене мултимедијске фајлове и одбија да их скида на даље. Небитно је за суспензију.
-      severities:
-        noop: Ништа
-        silence: Ућуткавање
-        suspend: Суспензија
-      severity: Оштрина
+      reject_media_hint: Уклања локално ускладиштене мултимедијске фајлове и одбија да их скида убудуће. Небитно је за суспензију
+      reject_reports: Одбаци извештај
+      reject_reports_hint: Игнориши све извештаје који долазе са овог домена. Небитно је за суспензије
+      rejecting_media: одбацивање медијских датотека
+      rejecting_reports: одбацивање пријава
+      severity:
+        silence: ућуткани
+        suspend: суспендовани
       show:
         affected_accounts:
           few: Утиче на %{count} налога у бази
           many: Утиче на %{count} налога у бази
-          one: Утиче на један налог у бази
-          other: Утиче на %{count} налога у бази
+          one: Један налог у бази података је под утицајем
+          other: Утиче на %{count} налога у бази података
         retroactive:
           silence: Угаси ућуткивање за све постојеће налоге са овог домена
-          suspend: Угаси суспензије за све постојеће налоге са овог домена
-        title: Поништи блокаду домена за домен %{domain}
+          suspend: Уклони суспензије за све постојеће налоге са овог домена
+        title: Поништи блокаду домена за %{domain}
         undo: Поништи
-      title: Блокаде домена
-      undo: Поништи
+      undo: Поништи блок домена
     email_domain_blocks:
-      add_new: Додај новуAdd new
-      created_msg: Успешно додао домен е-поште на црну листу
-      delete: Уклони
-      destroyed_msg: Успешно уклоњен домен е-поште са црне листе
+      add_new: Додај нови
+      created_msg: Успешно додао домен Е-поште на црну листу
+      delete: Обриши
+      destroyed_msg: Успешно уклоњен домен Е-поште са црне листе
       domain: Домен
       new:
         create: Додај домен
-        title: Нова ставка у црној листи е-пошти
-      title: Црна листа адреса е-поште
+        title: Нова ставка е-поштe у црној листи
+      title: Црна листа E-поште
+    followers:
+      back_to_account: Назад на налог
+      title: "%{acct} Пратиоци"
     instances:
-      account_count: Познати налози
-      domain_name: Домен
-      reset: Ресетуј
-      search: Претрага
-      title: Познате инстанце
+      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: Пријаве везане за њих
     invites:
+      deactivate_all: Деактивирај све
       filter:
         all: Све
-        available: Активне
-        expired: Истекле
+        available: Доступни
+        expired: Истекли
         title: Филтер
       title: Позивнице
+    relays:
+      add_new: Додај нови релеј
+      delete: Обриши
+      description_html: "<strong>Федерални релеј</strong> је посреднички сервер који размењује велике количине јавних труба између сервера на који је претплаћен и на који објављује.<strong>Може помоћи малим и средњим серверима да открију садржај из федиверса</strong>, који иначе захтева од локалних корисника да ручно пратити остале људе на удаљеним серверима."
+      disable: Искључи
+      disabled: Искључен
+      enable: Укључи
+      enable_hint: Када се омогући, Ваш сервер ће бити претплаћен на све јавне трубе са овог релеја, и почеће да шаље своје јавне трубу на њега.
+      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: Ништа
-      id: ID
-      mark_as_resolved: Означи као решен
+      created_at: Пријављена
+      mark_as_resolved: Означи као решену
+      mark_as_unresolved: Означи као нерешену
+      notes:
+        create: Додај белешку
+        create_and_resolve: Реши са белешком
+        create_and_unresolve: Отвори поново са белешком
+        delete: Обриши
+        placeholder: Опишите какве су радње предузете, или било какве повезане новости...
+      reopen: Отвори пријаву поново
       report: 'Пријава #%{id}'
-      report_contents: Садржај
       reported_account: Пријављени налог
       reported_by: Пријавио
-      resolved: Решени
-      silence_account: Ућуткај налог
+      resolved: Решена
+      resolved_msg: Пријава успешно разрешена!
       status: Статус
-      suspend_account: Суспендуј налог
-      target: Циљ
       title: Пријаве
-      unresolved: Нерешени
-      view: Погледај
+      unassign: Уклони доделу
+      unresolved: Нерешене
+      updated_at: Ажурирана
     settings:
+      activity_api_enabled:
+        desc_html: Бројеви локално објављених статуса, активних корисника и нових регистрација по недељама
+        title: Објављуј агрегиране статистике о корисничким активностима
       bootstrap_timeline_accounts:
         desc_html: Одвојите више корисничких имена зарезом. Ради само за локалне и откључане налоге. Ако је празно, онда се односи на све локалне администраторе.
         title: Налози за аутоматско запраћивање за нове кориснике
       contact_information:
         email: Пословна е-пошта
         username: Контакт корисничко име
+      custom_css:
+        desc_html: Промени изглед на свакој страни када се CSS учита
+        title: Произвољни CSS
+      hero:
+        desc_html: Приказано на почетној страни. Препоручено је бар 600х100рх. Када се не одреди, враћа се на иконицу инстанце
+        title: Лого слика
+      mascot:
+        desc_html: Приказано на више страна. Препоручено је бар 293×205px. Када није постављена, користи се подразумевана маскота
+        title: Слика маскоте
+      peers_api_enabled:
+        desc_html: Имена домена које је ова инстанца срела у федиверсу
+        title: Објављуј списак откривених инстанци
+      preview_sensitive_media:
+        desc_html: Преглед веза на другим веб страницама ће приказати иконицу чак и ако је медиј означен као осетљиво
+        title: Покажи осетљив медиј у ОпенГраф прегледу
+      profile_directory:
+        desc_html: Дозволи корисницима да буду откривени
+        title: Омогући профил фасцикле
       registrations:
         closed_message:
           desc_html: Приказује се на главној страни када је инстанца затворена за регистрације. Можете користити HTML тагове
@@ -285,6 +424,9 @@ sr:
         open:
           desc_html: Дозволи свакоме да креира налог
           title: Отворена регистрација
+      show_known_fediverse_at_about_page:
+        desc_html: Када се упали, показаће трубе из свих знаних федиверса на преглед. У супротном ће само показати локалне трубе.
+        title: Покажи познате здружене инстанце у прегледнику временске линије
       show_staff_badge:
         desc_html: Прикажи беџ особља на корисничкој страни
         title: Прикажи беџ особља
@@ -294,6 +436,9 @@ sr:
       site_description_extended:
         desc_html: Добро место за ваш код понашања, правила, смернице и друге ствари по којима се Ваша инстанца разликује. Можете користити HTML тагове
         title: Произвољне додатне информације
+      site_short_description:
+        desc_html: Приказано у изборнику са стране и у мета ознакама. Опиши шта је Мастодон и шта чини овај сервер посебним у једном пасусу. Ако остане празно, вратиће се првобитни опис инстанце.
+        title: Кратак опис инстанце
       site_terms:
         desc_html: Можете писати Вашу политику приватности, услове коришћења и остале легалне ствари. Можете користити HTML тагове
         title: Произвољни услови коришћења
@@ -315,6 +460,7 @@ sr:
       media:
         title: Мултимедија
       no_media: Без мултимедије
+      no_status_selected: Ниједан статус није промењен јер ниједан није изабран
       title: Статуси налога
       with_media: Са мултимедијом
     subscriptions:
@@ -324,15 +470,33 @@ sr:
       last_delivery: Последња достава
       title: WebSub
       topic: Topic
+    tags:
+      accounts: Налози
+      hidden: Скривено
+      hide: Сакриј од фасцикле
+      name: Тараба
+      title: Тараба
+      unhide: Прикажи у фасцикли
+      visible: Видљиво
     title: Администрација
+    warning_presets:
+      add_new: Додај нови
+      delete: Избриши
+      edit: Уреди
+      edit_preset: Уреди пресет упозорења
+      title: Управљај пресетима упозорења
   admin_mailer:
     new_report:
       body: "%{reporter} је пријавио %{target}"
+      body_remote: Нека са домена %{domain} је пријавио %{target}
       subject: Нова пријава за %{instance} (#%{id})
   application_mailer:
+    notification_preferences: Промени преференце Е-поште
     salutation: "%{name},"
     settings: 'Промени подешавања е-поште: %{link}'
     view: 'Погледај:'
+    view_profile: Погледај профил
+    view_status: Погледај статус
   applications:
     created: Апликација успешно направљена
     destroyed: Апликација успешно обрисана
@@ -343,6 +507,8 @@ sr:
     your_token: Ваш приступни токен
   auth:
     agreement_html: Приступањем инстанци се слажете са <a href="%{rules_path}">правилима инстанце</a> и <a href="%{terms_path}">условима коришћења</a>.
+    change_password: Лозинка
+    confirm_email: Потврдите адресу е-поште
     delete_account: Обриши налог
     delete_account_html: Ако желите да обришете Ваш налог, можете <a href="%{path}">наставити овде</a>. Бићете упитани да потврдите.
     didnt_get_confirmation: Нисте добили поруку са упутствима за потврду налога?
@@ -352,12 +518,19 @@ 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: Безбедност
     set_new_password: Постави нову лозинку
   authorize_follow:
+    already_following: Већ пратите овај налог
     error: Нажалост, десила се грешка при тражењу удаљеног налога
     follow: Запрати
     follow_request: 'Послали сте захтев за праћењен за:'
@@ -389,24 +562,59 @@ sr:
     success_msg: Ваш налог је успешно обрисан
     warning_html: Гарантовано је само брисање садржаја са ове инстанце. Садржај који је дељен даље ће вероватно да остави неке трагове. Недоступни и угашени сервери, као и сервери који су одјављени од примања статуса од Вас, неће ажурирати своје базе.
     warning_title: Доступност расејаног садржаја
+  directories:
+    directory: Профил фасцикле
+    enabled: Ви сте тренутно видљиви у фасцикли.
+    explanation: Откријте кориснике на основу њихових интереса
+    explore_mastodon: Истражи %{title}
+    people:
+      few: "%{count} људе"
+      many: "%{count} људе"
+      one: "%{count} особу"
+      other: "%{count} људе"
   errors:
     '403': Немате дозвола да видите ову страну.
     '404': Страна коју сте тражили не постоји.
     '410': Страна коју сте тражили више не постоји.
     '422':
-      content: Security verification failed. Are you blocking cookies?
-      title: Security verification failed
+      content: Безбедоносна провера није успела. Да не блокирате колачиће?
+      title: Безбедоносна провера није успела
     '429': Успоред
     '500':
       content: Извињавамо се, нешто је пошло по злу са ове стране.
       title: Страна није исправна
-    noscript_html: Да бисте користили Мастодонт веб апликацију, омогућите JavaScript. У супротном, пробајте неку од <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">оригиналних апликација</a> за Мастодонт за Вашу платформу.
+    noscript_html: Да бисте користили Мастодонт веб апликацију, омогућите JavaScript. У супротном, пробајте неку од <a href="%{apps_path}">оригиналних апликација</a> за Мастодонт за Вашу платформу.
   exports:
+    archive_takeout:
+      date: Датум
+      download: Преузмите Вашу архиву
+      hint_html: Можете затражити архиву ваших <strong>труба и отпремљених медија</strong>. Извезени подаци ће бити у АктивитиПаб формату, који можете читати са било којим усаглашеним софтвером. Архиву можете затражити сваких 7 дана.
+      in_progress: Састављање ваше архиве...
+      request: Затражите Вашу архиву
+      size: Величина
     blocks: Блокирали сте
     csv: CSV
+    domain_blocks: Блокови домена
     follows: Пратите
+    lists: Листе
     mutes: Ућуткали сте
     storage: Мултимедијално складиште
+  filters:
+    contexts:
+      home: Временска линија почетне
+      notifications: Обавештења
+      public: Јавна временска линија
+      thread: Разговори
+    edit:
+      title: Измени филтер
+    errors:
+      invalid_context: Ниједан или неважећи контекст испоручен
+      invalid_irreversible: Неповратно филтрирање функционише само са почетном или контекстом обавештења
+    index:
+      delete: Избриши
+      title: Филтери
+    new:
+      title: Додај нови филтер
   followers:
     domain: Домен
     explanation_html: Ако желите да осигурате приватност Ваших статуса, морате бити свесни ко Вас прати. <strong>Ваши приватни статуси се шаљу на све инстанце на којима имате пратиоце</strong>. Можда желите да их прегледате и да уклоните оне пратиоце на оним инстанцама за које немате поверења да ће поштовати Вашу приватност.
@@ -421,9 +629,13 @@ sr:
     true_privacy_html: Запамтите да се <strong>права приватност може постићи само шифровањем са краја на крај</strong>.
     unlocked_warning_html: Свако може да Вас запрати да одмах види Ваше приватне статусе. %{lock_link} да бисте прегледали и одбацили пратиоце.
     unlocked_warning_title: Ваш налог није закључан
+  footer:
+    developers: Програмери
+    more: Више…
+    resources: Ресурси
   generic:
     changes_saved_msg: Измене успешно сачуване!
-    powered_by: омогућио %{link}
+    copy: Копирај
     save_changes: Сними измене
     validation_errors:
       few: Нешто није баш како треба! Прегледајте %{count} грешке испод
@@ -447,9 +659,11 @@ sr:
       '21600': 6 сати
       '3600': 1 сад
       '43200': 12 сати
+      '604800': 1 недеља
       '86400': 1 дан
     expires_in_prompt: Никад
     generate: Генериши
+    invited_by: 'Позвао Вас је:'
     max_uses:
       few: "%{count} коришћења"
       many: "%{count} коришћења"
@@ -460,9 +674,7 @@ sr:
     table:
       expires_at: Истиче
       uses: Коришћења
-    title: Позови људе
-  landing_strip_html: "<strong>%{name}</strong> је корисник на %{link_to_root_path}. Можете га запратити или комуницирати са њим ако имте налог било где у федиверсу."
-  landing_strip_signup_html: Ако немате, можете се <a href="%{sign_up_path}">регистровати овде</a>.
+    title: Позовите људе
   lists:
     errors:
       limit: Достигли сте лимит броја листи
@@ -479,7 +691,8 @@ sr:
     title: Модерација
   notification_mailer:
     digest:
-      body: 'Ево кратак преглед шта сте пропустили на инстанци %{instance} од последње посете од %{since}:'
+      action: Погледајте сва обавештења
+      body: Ево кратак преглед порука које сте пропустили од последње посете од %{since}
       mention: "%{name} Вас је поменуо у:"
       new_followers_summary:
         few: Добили сте %{count} нова пратиоца! Сјајно!
@@ -491,21 +704,29 @@ sr:
         many: "%{count} нових обавештења од последње посете \U0001F418"
         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} је подржао(ла) Ваш статус"
+      body: "%{name} Вам је подржао/ла статус:"
+      subject: "%{name} је подржао/ла Ваш статус"
+      title: Нова подршка
   number:
     human:
       decimal_units:
@@ -518,51 +739,72 @@ sr:
           trillion: T
           unit: ''
   pagination:
-    next: Следећи
+    newer: Новије
+    next: Следеће
+    older: Старије
     prev: Претходни
     truncate: "&hellip;"
   preferences:
     languages: Језици
-    other: Остали
+    other: Остало
     publishing: Објављивање
     web: Веб
   remote_follow:
     acct: Унесите Ваш корисник@домен са кога желите да пратите
     missing_resource: Не могу да нађем захтевану адресу преусмеравања за Ваш налог
-    proceed: Наставите да запратите
-    prompt: 'Запратите ће:'
+    no_account_html: Немате налог? Можете се <a href='%{sign_up_path}' target='_blank'>пријавити овде</a>
+    proceed: Наставите да би сте запратили
+    prompt: 'Запратићете:'
+    reason_html: "<strong>Зашто је овај корак неопходан?</strong><code>%{instance}</code> можда није сервер на којем сте регистровани, тако да прво морамо да вас преусмеримо на ваш сервер."
+  remote_interaction:
+    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: Alipay
-      blackberry: Блекбери
+      alipay: Алипеј
+      blackberry: Блекберија
       chrome: Хром
-      edge: Microsoft Edge
-      firefox: Firefox
+      edge: Мајкрософт Еџ
+      electron: Електрон
+      firefox: Фајерфокс
       generic: Непознати веб читач
-      ie: Internet Explorer
-      micro_messenger: MicroMessenger
-      nokia: Nokia S40 Ovi Browser
+      ie: Интернет Експлорер
+      micro_messenger: МајкроМесенџер
+      nokia: Нокија С40 Ови Претраживач
       opera: Опера
-      phantom_js: PhantomJS
-      qq: QQ Browser
+      otter: Отер
+      phantom_js: ФантомЏејЕс
+      qq: КјуКју Претраживач
       safari: Сафари
-      uc_browser: UCBrowser
-      weibo: Weibo
+      uc_browser: УЦПретраживач
+      weibo: Веибо
     current_session: Тренутна сесија
     description: "%{browser} са %{platform}"
-    explanation: Ово су тренутно пријављени веб читачи на Ваш Мастодонт налог.
+    explanation: Ово су веб претраживачи који су тренутно пријављени на Ваш Мастодон налог.
     ip: IP
     platforms:
-      adobe_air: Adobe Air-а
+      adobe_air: Адоб Ер-а
       android: Андроида
       blackberry: Блекберија
       chrome_os: Хром ОС-а
       firefox_os: Фајерфокс ОС-а
-      ios: iOS
+      ios: иОС-а
       linux: Линукса
-      mac: Mac-а
+      mac: Мека
       other: непознате платформе
       windows: Виндоуза
       windows_mobile: Виндоуз мобилног
@@ -572,7 +814,7 @@ sr:
     title: Сесије
   settings:
     authorized_apps: Ауторизоване апликације
-    back: Назад на Мастодонта
+    back: Назад на Мастодон
     delete: Брисање налога
     development: Развој
     edit_profile: Измена профила
@@ -586,51 +828,118 @@ sr:
     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 откривање језика
     open_in_web: Отвори у вебу
     over_character_limit: ограничење од %{max} карактера прекорачено
     pin_errors:
-      limit: Већ имате прикачен највећи број тутова
-      ownership: Туђи тутови не могу да се прикаче
-      private: Тутови који нису јавни не могу да се прикаче
+      limit: Већ имате прикачен највећи број труба
+      ownership: Туђе трубе не могу да се прикаче
+      private: Трубе које нису јавне не могу бити прикачене
       reblog: Подршка не може да се прикачи
     show_more: Прикажи још
+    sign_in_to_participate: Пријавите се да учествујете у разговору
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Само пратиоци
-      private_long: Само прикажи пратиоцима
+      private_long: Прикажи само пратиоцима
       public: Јавно
       public_long: Свако може да види
       unlisted: Неизлистано
-      unlisted_long: Свако може да види, али није излистано на јавним лајнама
+      unlisted_long: Свако може да види, али није излистано на јавним временским линијама
   stream_entries:
-    click_to_show: Кликни да видиш
-    pinned: Прикачени тут
+    pinned: Прикачена труба
     reblogged: подржано
     sensitive_content: Осетљив садржај
   terms:
     title: Услови коришћења и политика приватности инстанце %{instance}
   themes:
-    default: Мастодонт
+    contrast: Велики контраст
+    default: Мастодон
+    mastodon-light: Мастодон (светло)
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
-    code_hint: Унесите код са Ваше апликације за проверу идентитета да потврдите
+    code_hint: Да бисте потврдили, унесите код генерисан од стране ваше апликације за потврду идентитета
     description_html: Ако укључите <strong>двофакторску идентификацију</strong>, мораћете да имате телефон са собом да бисте могли да се пријавите. Телефон ће онда генерисати токене за Вашу пријаву.
     disable: Искључи
-    enable: Укључи
+    enable: Омогући
     enabled: Двофакторска идентификација је укључена
     enabled_success: Двофакторска идентификација је успешно укључена
     generate_recovery_codes: Генериши кодове за опоравак
     instructions_html: "<strong>Скенирајте овај QR код у Google Authenticator или некој сличној TOTP апликацији на Вашем телефону</strong>. Од сада, та апликација ће Вам генерисати токене које морате унети да бисте се пријавили."
-    lost_recovery_codes: Кодови за опоравак Вам омогућавају да повратите приступ налогу ако изгубите телефон. Ако изгубите кодове за опоравак, можете их регенерисати овде. Од тог тренутка, стари кодови за опоравак више не важе.
+    lost_recovery_codes: Кодови за опоравак Вам омогућавају да повратите приступ налогу ако изгубите телефон. Ако изгубите кодове за опоравак, можете их ре-генерисати овде. Од тог тренутка, стари кодови за опоравак више не важе.
     manual_instructions: 'Уколико не можете да скенирате QR код и морате га унесете ручно, ево је огољена шифра:'
     recovery_codes: Направите резерву кодова за опоравак
-    recovery_codes_regenerated: Кодови за опоравак успешно регенерисани
+    recovery_codes_regenerated: Кодови за опоравак успешно ре-генерисани
     recovery_instructions_html: Ако икада изгубите приступ телефону, можете искористити кодове за опоравак дате испод да повратите приступ налогу. <strong>Држите кодове за опоравак на сигурном</strong>. На пример, одштампајте их и чувајте их са осталим важним документима.
     setup: Намештање
     wrong_code: Унесени код није исправан! Да ли су времена на серверу и на уређају исправна?
+  user_mailer:
+    backup_ready:
+      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: Профил можете прилагодити постављањем аватара, заглавља, променом имена и још много тога. Ако желите да прегледате нове пратиоце пре него што буду дозвољени да вас прате, можете закључати свој налог.
+      explanation: Ево неколико савета за почетак
+      final_action: Почните објављивати
+      final_step: 'Почните објављивати! Чак и без пратиоца ваше јавне поруке ће бити виђене од стране других, нпр. на локалној јавног линији и у тараба за означавање. Можда бисте желели да се представите у #увод тараби за означавање.'
+      full_handle: Ваш пун надимак
+      full_handle_hint: Ово бисте рекли својим пријатељима како би вам они послали поруку, или запратили са друге инстанце.
+      review_preferences_action: Промените подешавања
+      review_preferences_step: Обавезно поставите своја подешавања, као што су какву Е-пошту желите да примите или на који ниво приватности желите да ваше поруке буду постављене. Ако немате морску болест или епилепсију, можете изабрати аутоматско покретање ГИФ-а.
+      subject: Добродошли на Мастодон
+      tip_federated_timeline: Здружена временска линија пружа комплетан увид у Мастодонову мрежу. Али она само укључује људе на које су ваше комшије претплаћене, тако да није комплетна.
+      tip_following: Аутоматски пратите админа/не вашег сервера. Да пронађете занимљиве људе, проверите локалне и здружене временске линије.
+      tip_local_timeline: Локална временска линија је комплетан увид људи у %{instance}.  Ово су вам прве комшије!
+      tip_mobile_webapp: Ако вам мобилни претраживач предложи да додате Мастодон на Ваш почетни екран, добијаћете мобилна обавештења. Делује као изворна апликација на много начина!
+      tips: Савети
+      title: Добродошли, %{name}!
   users:
-    invalid_email: Адреса е-поште није исправна
+    follow_limit_reached: Не можете пратити више од %{limit} људи
+    invalid_email: Адреса Е-поште није исправна
     invalid_otp_token: Неисправни двофакторски код
-    signed_in_as: 'Пријављен као:'
+    otp_lost_help_html: Ако изгубите приступ за оба, можете ступити у контакт са %{email}
+    seamless_external_login: Пријављени сте путем спољашње услуге, тако да лозинка и подешавања Е-поште нису доступни.
+    signed_in_as: 'Пријављен/а као:'
+  verification:
+    explanation_html: 'Можете <strong>извршити проверу да сте Ви власник веза у Вашем профилу</strong>. Да би то радило, повезани веб сајт мора да садржи везу назад ка Вашем Мастодон профилу. Веза назад <strong>мора</strong> да има <code>rel="me"</code> атрибут. Текстуелни садржај везе није битан. Ево примера:'
+    verification: Провера
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 70735fc051181b4292b3fab2a2c4c4444b98e837..3a006ebe5a1126b3e4b0b98ac2fe2ce51003d455 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -9,9 +9,6 @@ sv:
     contact: Kontakt
     contact_missing: Inte inställd
     contact_unavailable: N/A
-    description_headline: Vad är %{domain}?
-    domain_count_after: andra instanser
-    domain_count_before: Uppkopplad mot
     extended_description_html: |
       <h3>En bra plats för regler</h3>
       <p>Den utökade beskrivningen har inte konfigurerats ännu.</p>
@@ -46,7 +43,6 @@ sv:
     people_who_follow: Personer som följer %{name}
     posts: Toots
     posts_with_replies: Toots med svar
-    remote_follow: Avlägsen följare
     reserved_username: Användarnamnet är reserverat
     roles:
       admin: Admin
@@ -107,10 +103,6 @@ sv:
       most_recent_activity: Senaste aktivitet
       most_recent_ip: Senaste IP
       not_subscribed: Inte prenumererat
-      order:
-        alphabetic: Alfabetiskt
-        most_recent: Senaste
-        title: Ordning
       outbox_url: Utkorg URL
       perform_full_suspension: Utför full avstängning
       profile_url: Profil URL
@@ -138,7 +130,6 @@ sv:
       shared_inbox_url: Delad inkorg URL
       show:
         created_reports: Anmälningar som skapats av det här kontot
-        report: anmäla
         targeted_reports: Anmälningar gjorda om detta konto
       silence: Tystnad
       statuses: Status
@@ -222,11 +213,6 @@ sv:
         title: Nytt domänblock
       reject_media: Avvisa mediafiler
       reject_media_hint: Raderar lokalt lagrade mediefiler och förhindrar möjligheten att ladda ner något i framtiden. Irrelevant för suspensioner
-      severities:
-        noop: Ingen
-        silence: Tysta ner
-        suspend: Suspendera
-      severity: Svårighet
       show:
         affected_accounts:
           one: Ett konto i databasen drabbades
@@ -236,7 +222,6 @@ sv:
           suspend: Ta bort suspendering från alla befintliga konton på den här domänen
         title: Ångra domänblockering för %{domain}
         undo: Ã…ngra
-      title: Domänblockering
       undo: Ã…ngra
     email_domain_blocks:
       add_new: Lägg till ny
@@ -249,10 +234,6 @@ sv:
         title: Ny E-postdomänblocklistningsinmatning
       title: E-postdomänblock
     instances:
-      account_count: Kända konton
-      domain_name: Domän
-      reset: Återställa
-      search: Sök
       title: Kända instanser
     invites:
       filter:
@@ -275,7 +256,6 @@ sv:
       comment:
         none: Ingen
       created_at: Anmäld
-      id: ID
       mark_as_resolved: Markera som löst
       mark_as_unresolved: Markera som olöst
       notes:
@@ -286,20 +266,15 @@ sv:
         placeholder: Beskriv vilka åtgärder som vidtagits eller andra uppdateringar till den här anmälan.
       reopen: Återuppta anmälan
       report: 'Anmäl #%{id}'
-      report_contents: Innehåll
       reported_account: Anmält konto
       reported_by: Anmäld av
       resolved: Löst
       resolved_msg: Anmälan har lösts framgångsrikt!
-      silence_account: Tysta ner konto
       status: Status
-      suspend_account: Suspendera konto
-      target: MÃ¥l
       title: Anmälningar
       unassign: Otilldela
       unresolved: Olösta
       updated_at: Uppdaterad
-      view: Granska
     settings:
       activity_api_enabled:
         desc_html: Räkning av lokalt postade statusar, aktiva användare och nyregistreringar per vecka
@@ -460,7 +435,7 @@ sv:
     '500':
       content: Vi är ledsna, men något gick fel från vårat håll.
       title: Den här sidan är inte korrekt
-    noscript_html: För att använda Mastodon webbapplikationen, vänligen aktivera JavaScript. Alternativt kan du prova en av <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">inhemska appar</a> för Mastodon för din plattform.
+    noscript_html: För att använda Mastodon webbapplikationen, vänligen aktivera JavaScript. Alternativt kan du prova en av <a href="%{apps_path}">inhemska appar</a> för Mastodon för din plattform.
   exports:
     archive_takeout:
       date: Datum
@@ -488,7 +463,6 @@ sv:
     unlocked_warning_title: Ditt konto är inte låst
   generic:
     changes_saved_msg: Ändringar sparades framgångsrikt!
-    powered_by: drivs av %{link}
     save_changes: Spara ändringar
     validation_errors:
       one: Något är inte riktigt rätt ännu! Kontrollera felet nedan
@@ -524,8 +498,6 @@ sv:
       expires_at: Utgår
       uses: Användningar
     title: Bjud in andra
-  landing_strip_html: "<strong>%{name}</strong> är en användare på %{link_to_root_path}. Du kan följa dem eller interagera med dem om du har ett konto någonstans i federationen."
-  landing_strip_signup_html: Om du inte gör det, så kan du <a href="%{sign_up_path}">registrera dig här</a>.
   lists:
     errors:
       limit: Du har nått det maximala antalet listor
@@ -693,7 +665,6 @@ sv:
       unlisted: Olistade
       unlisted_long: Alla kan se, men listas inte på offentliga tidslinjer
   stream_entries:
-    click_to_show: Klicka för att visa
     pinned: Fäst toot
     reblogged: boostad
     sensitive_content: Känsligt innehåll
@@ -819,10 +790,9 @@ sv:
       review_preferences_action: Ändra inställningar
       review_preferences_step: Se till att du ställer in dina inställningar, t.ex. vilka e-postmeddelanden du vill ta emot eller vilken integritetsnivå du vill att dina inlägg ska vara. Om du inte har åksjuka, kan du välja att aktivera automatisk uppspelning av GIF-bilder.
       subject: Välkommen till Mastodon
-      tip_bridge_html: Om du kommer från Twitter kan du hitta dina vänner på Mastodon genom att använda <a href="%{bridge_url}">bridge-appen</a>. Det fungerar dock bara om de också har använt bridge-appen!
       tip_federated_timeline: Den förenade tidslinjen är en störtflodsvy av Mastodon-nätverket. Men det inkluderar bara människor som dina grannar följer, så det är inte komplett.
       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_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}!
diff --git a/config/locales/te.yml b/config/locales/te.yml
index f28b5605237d8ac889b65382f233e9331413fb2a..f0f6942abffae70284d3d13adce95116501d787f 100644
--- a/config/locales/te.yml
+++ b/config/locales/te.yml
@@ -1,5 +1,129 @@
 ---
 te:
   about:
+    about_hashtag_html: ఇవి <strong>#%{hashtag}</strong>తో ట్గాగ్ చేయబడిన పబ్లిక్ టూట్లు. ఫెడివర్స్ లో ఎక్కడ ఖాతావున్నా వీటిలో పాల్గొనవచ్చు.
+    about_mastodon_html: మాస్టొడాన్ అనేది ఒక సామాజిక మాధ్యమం. ఇది పూర్తిగా ఉచితం మరియు స్వేచ్ఛా సాఫ్టువేరు. ఈమెయిల్ లాగానే ఇది వికేంద్రీకరించబడినది.
     about_this: గురించి
+    administered_by: 'నిర్వహణలో:'
+    api: API
+    apps: మొబైల్ యాప్స్
+    closed_registrations: ప్రస్తుతం ఈ ఇన్స్టెన్స్ లో రిజిస్టేషన్లు మూసివేయబడ్డాయి. అయితే, వేరే ఇన్స్టెన్స్ లో ఖాతా తెరచికూడా ఈ ఇన్స్టెన్స్ ను అక్కడినుండే యాక్సెస్ చేయవచ్చు.
     contact: సంప్రదించండి
+    contact_missing: ఇంకా సెట్ చేయలేదు
+    contact_unavailable: వర్తించదు
+    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: 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:
+      one: స్థితి
+      other: స్థితులు
+    status_count_before: ఎవరు రాశారు
+    terms: సేవా నిబంధనలు
+    user_count_after:
+      one: వినియోగదారు
+      other: వినియోగదారులు
+    user_count_before: హోం కు
+    what_is_mastodon: మాస్టొడాన్ అంటే ఏమిటి?
+  accounts:
+    choices_html: "%{name}'s ఎంపికలు:"
+    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: ఈ 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: ఖాతా యొక్క ఈమెయిల్ విజయవంతంగా మార్చబడింది!
+        current_email: ప్రస్తుత ఈమెయిల్
+        label: ఈమెయిల్ ను మార్చు
+        new_email: కొత్త ఈమెయిల్
+        submit: ఈమెయిల్ ను మార్చు
+        title: "%{username} యొక్క ఈమెయిల్ ను మార్చు"
+      confirm: ధృవీకరించు
+      confirmed: ధృవీకరించబడింది
+      confirming: ధృవీకరిస్తుంది
+      demote: స్థానం తగ్గించు
+      disable: అచేతనం చేయి
+      disable_two_factor_authentication: 2FAను అచేతనం చేయి
+      disabled: అచేతనం చేయబడింది
+      display_name: పేరును చూపు
+      domain: డొమైను
+      edit: మార్చు
+      email: ఈమెయిల్
+      email_status: ఈమెయిల్ స్థితి
+      enable: చేతనం
+      enabled: చేతనం చేయబడింది
+      feed_url: ఫీడ్ URL
+      followers: అనుచరులు
+      followers_url: అనుచరుల URL
+      follows: అనుసరిస్తున్నారు
+      header: Header
+      inbox_url: ఇన్ బాక్స్ URL
+      ip: IP
+      location:
+        all: అన్నీ
+        local: లోకల్
+        remote: రిమోట్
+        title: లొకేషన్
+      login_status: లాగిన్ స్థితి
+      media_attachments: మీడియా అటాచ్మెంట్లు
+      memorialize: Turn into memoriam
+      moderation:
+        active: యాక్టివ్
+        all: అన్నీ
+        silenced: నిశ్శబ్ధం చేయబడింది
+        suspended: నిషేధించబడింది
+        title: మోడరేషన్
+      moderation_notes: మోడరేషన్ నోట్స్
+      most_recent_activity: ఇటీవల యాక్టివిటీ
+      most_recent_ip: ఇటీవలి IP
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 6804dbd13d3b071f4b5a4d0de0935edb4b5c261c..5be8e02c0f0d36d470ac20e766141d299b7b91ec 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -5,9 +5,6 @@ th:
     about_this: เกี่ยวกับอินซะแตนซ์นี้
     closed_registrations: อินซะแตนซ์นี้ปิดรับลงทะเบียนแล้ว.
     contact: ติดต่อ
-    description_headline: โดเมนคือ %{domain} ?
-    domain_count_after: อินซะแตนซ์อื่นๆ
-    domain_count_before: เชื่อมต่อกับ
     other_instances: อินซะแตนซ์อื่นๆ
     source_code: ซอร์สโค๊ด
     status_count_after: สถานะ
@@ -22,7 +19,6 @@ th:
     people_followed_by: ถูกติดตามโดย %{name}
     people_who_follow: คนที่ติดตาม %{name}
     posts: โพสต์
-    remote_follow: Remote follow
     unfollow: เลิกติดตาม
   admin:
     accounts:
@@ -53,10 +49,6 @@ th:
       most_recent_activity: กิจกรรมล่าสุด
       most_recent_ip: IP ล่าสุด
       not_subscribed: Not subscribed
-      order:
-        alphabetic: ตามตัวอักษร
-        most_recent: ล่าสุด
-        title: จัดเรียง
       perform_full_suspension: Perform full suspension
       profile_url: Profile URL
       public: สาธารณะ
@@ -69,7 +61,6 @@ th:
       salmon_url: Salmon URL
       show:
         created_reports: รายงานที่ถูกสร้างโดย แอคเคาท์นี้
-        report: รายงาน
         targeted_reports: รายงานเกี่ยวกับแอคเคาท์นี้
       silence: ปิดเสียง
       statuses: สถานะ
@@ -93,10 +84,6 @@ th:
         title: การบล๊อกโดเมนใหม่
       reject_media: ไม่อนุมัติไฟล์สื่อ
       reject_media_hint: ลบไฟล์สื่อที่เก็บไว้ในเครื่อง และ ป้องกันการดาวน์โหลดในอนาคต. Irrelevant for suspensions
-      severities:
-        silence: ปิดเสียง
-        suspend: หยุดไว้
-      severity: Severity
       show:
         affected_accounts:
           one: มีผลต่อหนึ่งแอคเค๊าท์ในฐานข้อมูล
@@ -106,29 +93,20 @@ th:
           suspend: ยกเลิกการหยุดทุกแอคเค๊าท์จากโดเมน
         title: ยกเลิกการบล๊อกโดเมน %{domain}
         undo: ยกเลิก
-      title: บล๊อกโดเมน
       undo: ยกเลิก
     instances:
-      account_count: Known accounts
-      domain_name: ชื่อโดเมน
       title: Known Instances
     reports:
       comment:
         none: None
-      id: ไอดี
       mark_as_resolved: ทำเครื่องหมายว่าจัดการแล้ว
       report: 'Report #%{id}'
-      report_contents: เนื้อหา
       reported_account: รายงานแอคเคาท์
       reported_by: รายงานโดย
       resolved: จัดการแล้ว
-      silence_account: แอคเค๊าท์ที่ปิดเสียง
       status: สถานะ
-      suspend_account: แอคเค๊าท์ที่หยุดไว้
-      target: เป้าหมาย
       title: รายงาน
       unresolved: Unresolved
-      view: วิว
     settings:
       contact_information:
         email: กรอกที่อยู่อีเมล์สาธารณะ
@@ -216,7 +194,6 @@ th:
     unlocked_warning_title: แอคเค๊าท์ของคุณไม่ได้ล๊อค
   generic:
     changes_saved_msg: บันทึกการแก้ไขแล้ว!
-    powered_by: powered by %{link}
     save_changes: บันทึกการเปลี่ยนแปลง
     validation_errors:
       one: Something isn't quite right yet! Please review the error below
@@ -229,15 +206,13 @@ th:
       following: Following list
       muting: Muting list
     upload: Upload
-  landing_strip_html: "<strong>%{name}</strong> is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse."
-  landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
   media_attachments:
     validations:
       images_and_video: Cannot attach a video to a status that already contains images
       too_many: แนบมากกว่า 4 ไฟล์ไม่ได้
   notification_mailer:
     digest:
-      body: 'Here is a brief summary of what you missed on %{instance} since your last visit on %{since}:'
+      body: Here is a brief summary of the messages you missed since your last visit on %{since}
       mention: "%{name} ส่งข้อความถึงคุณ:"
       new_followers_summary:
         one: ยินดีด้วยคุณได้ผู้ติดตามคนใหม่! Yay!
@@ -302,7 +277,6 @@ th:
       unlisted: Unlisted
       unlisted_long: Everyone can see, but not listed on public timelines
   stream_entries:
-    click_to_show: คลิกเพื่อแสดง
     reblogged: boosted
     sensitive_content: Sensitive content
   time:
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index 8bafbface2f7ee69907359db5a152768aa456960..c38b73f2e25152ec365175a939cab7f97ecbdea4 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -5,9 +5,6 @@ tr:
     about_this: Bu sunucu hakkında
     closed_registrations: Bu sunucu şu anda yeni kayıt almamaktadır.
     contact: İletişim
-    description_headline: Peki %{domain} nedir?
-    domain_count_after: sunucu var.
-    domain_count_before: Bağlı olduğu
     other_instances: DiÄŸer sunucular
     source_code: Kaynak kodu
     status_count_after: adet gönderi yazıldı.
@@ -22,7 +19,6 @@ tr:
     people_followed_by: Kullanıcı %{name}'in takip ettikleri
     people_who_follow: Kullanıcı %{name}'i takip edenler
     posts: Gönderiler
-    remote_follow: Uzaktan takip et
     unfollow: Takibi bırak
   admin:
     accounts:
@@ -52,10 +48,6 @@ tr:
       most_recent_activity: Son aktivite
       most_recent_ip: Son IP
       not_subscribed: Abone edilmedi
-      order:
-        alphabetic: Alfabetik
-        most_recent: En son
-        title: Sıralama
       perform_full_suspension: Tamamen uzaklaştır
       profile_url: Profil linki
       public: Herkese açık
@@ -68,7 +60,6 @@ tr:
       salmon_url: Salmon Linki
       show:
         created_reports: Bu hesap tarafından gelen şikayetler
-        report: ÅŸikayet
         targeted_reports: Bu hesaba gelen ÅŸikayetler
       silence: Sustur
       statuses: Durumlar
@@ -91,50 +82,37 @@ tr:
           suspend: Uzaklaştır
         title: Yeni domain bloÄŸu
       reject_media: Ortam dosyalarını reddetme
-      reject_media_hint: Yerel olarak depolanmış ortam dosyalarını ve gelecekte indirilecek olanları reddeder. Uzaklaştırma için uygun değildir.
-      severities:
-        silence: Sustur
-        suspend: Uzaklaştır
-      severity: İşlem
+      reject_media_hint: Yerel olarak depolanmış ortam dosyalarını ve gelecekte indirilecek olanları reddeder. Uzaklaştırma için uygun değildir
       show:
         affected_accounts:
           one: Veritabanındaki bir hesap etkilendi
           other: Veritabanındaki %{count} hesap etkilendi
         retroactive:
-          silence: Bu domaindeki tüm hesapların üzerindeki susturulma işlemini kaldır.
-          suspend: Bu domaindeki tüm hesapların üzerindeki uzaklaştırma işlemini kaldır.
+          silence: Bu domaindeki tüm hesapların üzerindeki susturulma işlemini kaldır
+          suspend: Bu domaindeki tüm hesapların üzerindeki uzaklaştırma işlemini kaldır
         title: "%{domain} domain'i için yapılan işlemi geri al"
         undo: Geri al
-      title: Domain Blokları
       undo: Geri al
     instances:
-      account_count: Bilinen hesaplar
-      domain_name: Domain
       title: Bilinen Sunucular
     reports:
       comment:
         none: Yok
-      id: ID
       mark_as_resolved: Giderildi olarak iÅŸaretle
       report: 'Åžikayet #%{id}'
-      report_contents: İçerik
       reported_account: Åžikayet edilen hesap
       reported_by: Åžikayet eden
       resolved: Giderildi
-      silence_account: Hesabı sustur
       status: Durum
-      suspend_account: Hesabı uzaklaştır
-      target: Hedef
       title: Åžikayetler
       unresolved: Giderilmedi
-      view: Görüntüle
     settings:
       contact_information:
         email: Herkese açık e-posta adresiniz
         username: Bir kullanıcı adı giriniz
       registrations:
         closed_message:
-          desc_html: Kayıt alımları kapatıldığında ana sayfada görüntülenecek mesajdır. <br> HTML etiketleri kullanabilirsiniz.
+          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ı
@@ -142,7 +120,7 @@ tr:
         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ı
       site_description_extended:
-        desc_html: Harici bilgi sayfasında gösterilir.<br>HTML etiketleri girebilirsiniz.
+        desc_html: Harici bilgi sayfasında gösterilir.<br>HTML etiketleri girebilirsiniz
         title: Sunucu hakkında detaylı bilgi
       site_title: Site başlığı
       title: Site Ayarları
@@ -170,7 +148,7 @@ tr:
     security: Kimlik bilgileri
     set_new_password: Yeni parola oluÅŸtur
   authorize_follow:
-    error: Uzak hesap aranırken bir hata oluştu.
+    error: Uzak hesap aranırken bir hata oluştu
     follow: Takip et
     title: "%{acct}'i takip et"
   datetime:
@@ -214,7 +192,6 @@ tr:
     unlocked_warning_title: Hesabınız kilitlendi
   generic:
     changes_saved_msg: Değişiklikler başarıyla kaydedildi!
-    powered_by: powered by %{link}
     save_changes: DeÄŸiÅŸiklikleri kaydet
     validation_errors:
       one: Bir şeyler ters gitti! Lütfen aşağıdaki hatayı gözden geçiriniz
@@ -227,15 +204,13 @@ tr:
       following: Takip edilenler listesi
       muting: Susturulanlar listesi
     upload: Yükle
-  landing_strip_html: "<strong>%{name}</strong>, %{link_to_root_path} sunucusundaki bir kullanıcıdır. Onu takip edebilir, veya Mastodon ağındaki bir hesabınızı kullanarak etkileşime geçebilirsiniz."
-  landing_strip_signup_html: Eğer hesabınız yoksa <a href="%{sign_up_path}">buradan kaydolabilirsiniz</a>.
   media_attachments:
     validations:
-      images_and_video: Halihazırda görsel içeren bir gönderiye video ekleyemezsiniz.
+      images_and_video: Halihazırda görsel içeren bir gönderiye video ekleyemezsiniz
       too_many: 4'ten fazla dosya ekleyemezsiniz
   notification_mailer:
     digest:
-      body: 'Son ziyaretiniz olan %{since}''den beri %{instance}''da kaçırdığınız şeylerin özeti:'
+      body: Son ziyaretiniz olan %{since}'den beri'da kaçırdığınız şeylerin özeti
       mention: "%{name} senden bahsetti:"
       new_followers_summary:
         one: Yeni bir takipçiniz var!
@@ -298,9 +273,8 @@ tr:
       public: Herkese açık
       public_long: Herkese açık zaman tüneline gönder
       unlisted: ListelenmemiÅŸ
-      unlisted_long: Herkes görebilir fakat herkese açık zaman tünellerinde listelenmez.
+      unlisted_long: Herkes görebilir fakat herkese açık zaman tünellerinde listelenmez
   stream_entries:
-    click_to_show: Görüntülemek için tıklayınız
     reblogged: boost edildi
     sensitive_content: Hassas içerik
   time:
@@ -311,7 +285,7 @@ tr:
     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.
     disable: Devre dışı bırak
     enable: AktifleÅŸtir
-    enabled_success: İki-faktörlü kimlik doğrulama başarıyla aktif edildi.
+    enabled_success: İki-faktörlü kimlik doğrulama başarıyla aktif edildi
     generate_recovery_codes: Kurtarma Kodlarını Oluştur
     instructions_html: <strong>Bu QR kodunu, telefonunuzdaki <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Google Authenticator</a> veya benzer bir TOTP uygulamasıyla taratınız</strong>. Bundan sonra giriş yaparken uygulamanın ürettiği kodu kullanarak giriş yapacaksınız.
     lost_recovery_codes: Kurtarma kodları telefonunuzu kaybettiğiniz durumlarda hesabınıza erişim yapabilmenize olanak tanır. Eğer kurtarma kodlarınızı kaybettiyseniz burada tekrar oluşturabilirsiniz. Eski kurtarma kodlarınız geçersiz hale gelecektir.
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index 6fe46b4d981655ad39129247141ed5c6a453c7b3..9a63854b5821a064a667315c72153a88d2956699 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -1,70 +1,226 @@
 ---
 uk:
   about:
+    about_hashtag_html: Немає публічних постів з хештегом<strong>#%{hashtag}</strong>. Ви можете  You can interact with them if you have an account anywhere in the fediverse.
     about_mastodon_html: Mastodon - це <em>вільна</em> соціальна мережа з <em>відкритим вихідним кодом</em>. Вона є <em>децентралізованою</em> альтернативою комерційним платформам, що дозволяє уникнути ризиків монополізації вашого спілкування однією компанією. Виберіть сервер, якому ви довіряєте &mdash; що б ви не вибрали, Ви зможете спілкуватись з усіма іншими. Будь-який користувач може запустити власну інстанцію Mastodon та без проблем брати участь в <em>соціальній мережі</em>.
     about_this: Про цю інстанцію
+    administered_by: 'Адміністратор:'
+    api: API
     closed_registrations: На даний момент реєстрація на цій інстанції закрита.
     contact: Зв'язатися
-    description_headline: Що таке %{domain}?
-    domain_count_after: іншими інстанціями
-    domain_count_before: Зв'язаний з
+    contact_missing: Не зазначено
+    contact_unavailable: Недоступно
+    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: Висловлюйте свої думки себе у будь-який спосіб маючи в розпорядженні 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: Медіа
+    moved_html: "%{name} переїхав на %{new_profile_link}:"
+    network_hidden: Ця інформація недоступна
     nothing_here: Тут нічого немає!
     people_followed_by: Люди, на яких підписаний(-а) %{name}
     people_who_follow: Підписники %{name}
     posts: Пости
-    remote_follow: Підписатися на іншій інстанції
+    posts_with_replies: Пости і відповіді
+    reserved_username: Це ім'я користувача зарезервоване
+    roles:
+      admin: Адміністратор
+      bot: Бот
+      moderator: Мод
     unfollow: Відписатися
   admin:
+    account_moderation_notes:
+      create: Залишити примітки
+      created_msg: Примітку модератора успішно створено!
+      delete: Видалити
+      destroyed_msg: Примітку модератора успішно видалено!
     accounts:
       are_you_sure: Ви впевнені?
+      avatar: Аватар
+      by_domain: Домен
+      change_email:
+        changed_msg: Поштова адреса аккаунту успішно змінена!
+        current_email: Поточна поштова адреса
+        label: Змінити поштову адресу
+        new_email: Новий e-mail
+        submit: Змінити поштову адресу
+        title: Змінити поштову адресу для %{username}
+      confirm: Зберегти
+      confirmed: Збережено
+      confirming: Зберігається
+      demote: Усунути
+      disable: Вимкнути
+      disable_two_factor_authentication: Вимкнути двофакторну авторизацію
+      disabled: Вимкнено
       display_name: Відображуване ім'я
       domain: Домен
       edit: Змінити
       email: Email
+      email_status: Статус e-mail
+      enable: Увімкнути
+      enabled: Увімкнено
       feed_url: URL фіду
       followers: Підписники
+      followers_url: URL підписників
       follows: Підписки
+      inbox_url: Вхідний URL
+      ip: IP
       location:
         all: Усі
         local: Локальні
         remote: Віддалені
         title: Розміщення
+      login_status: Статус авторизації
       media_attachments: Мультимедійні вкладення
+      memorialize: Зробити пам'ятником
       moderation:
         all: Усі
         silenced: Заглушені
         suspended: Заблоковані
         title: Модерація
+      moderation_notes: Примітки модераторів
       most_recent_activity: Остання активність
       most_recent_ip: Останній IP
       not_subscribed: Не підписані
-      order:
-        alphabetic: За алфавітом
-        most_recent: За датою
-        title: Порядок
+      outbox_url: Вихідний URL
       perform_full_suspension: Повне блокування
       profile_url: URL профілю
+      promote: Просунути
+      protocol: Протокол
       public: Публічний
       push_subscription_expires: Підписка PuSH спливає
+      redownload: Оновити аватар
+      remove_avatar: Видалити аватар
+      resend_confirmation:
+        already_confirmed: Цей користувач уже підтверджений
+        send: Надіслати підтвердження ще раз
+        success: Повідомлення з підтвердженням успішно надіслано!
+      reset: Скинути
       reset_password: Зкинути пароль
+      resubscribe: Перепідписатися
+      role: Дозволи
+      roles:
+        admin: Адміністратор
+        moderator: Модератор
+        staff: Персонал
+        user: Користувач
       salmon_url: Salmon URL
+      search: Пошук
+      shared_inbox_url: URL спільного вхідного кошика
+      show:
+        created_reports: Скарги створені цим аккаунтом
+        targeted_reports: Скарги щодо цього аккаунту
       silence: Глушення
       statuses: Статуси
+      subscribe: Підписатися
       title: Акаунти
+      unconfirmed_email: Непідтверджений e-mail
       undo_silenced: Зняти глушення
       undo_suspension: Зняти блокування
+      unsubscribe: Відписатися
       username: Ім'я користувача
       web: WWW
+    action_logs:
+      actions:
+        assigned_to_self_report: "%{name} призначив(-ла) скаргу %{target} на себе"
+        change_email_user: "%{name} змінив(-ла) поштову адресу користувача %{target}"
+        confirm_user: "%{name} підтвердив(-ла) статус поштової адреси користувача %{target}"
+        create_custom_emoji: "%{name} вивантажив(-ла) нове емодзі %{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} додав(-ла) поштовий домен %{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}"
+      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 розміром до 50 КБ
+      listed: У списку
+      new:
+        title: Додати новий емодзі
+      overwrite: Переписати
+      shortcode: Шорткод
+      shortcode_hint: Мінімум два символи, тільки цифрові й латинські символи або нижні підкреслення
+      title: Особливі емодзі
+      unlisted: Не у списку
+      update_failed_msg: Не вийшло оновити емозді
+      updated_msg: Емодзі успішно оновлене!
+      upload: Вивантажити
+    dashboard:
+      config: Налаштування
+      feature_deletions: Видалення аккаунтів
+      feature_invites: Посилання-запрошення
+      feature_registrations: Реєстрації
+      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: Блокування домену оброблюється
@@ -72,18 +228,15 @@ uk:
       domain: Домен
       new:
         create: Створити блокування
-        hint: Блокування домену не запобіжить створенню нових акаунтів у базі даних, але ретроактивно та автоматично застосує указані методи модерації для цих акаунтів.
+        hint: Блокування домену не завадить створенню нових акаунтів у базі даних, але ретроактивно та автоматично застосує вказані методи модерації для цих акаунтів.
         severity:
-          desc_html: "<strong>Глушення</strong> зробить статуси акаунту невидимими для всіх, крім їхніх підписників. <strong>Блокування</strong> видалить увесь контент акаунту, включаючи мультимедійні вкладення та дані профілю."
+          desc_html: "<strong>Глушення</strong> зробить статуси акаунту невидимими для всіх, окрім їхніх підписників. <strong>Блокування</strong> видалить увесь контент акаунту, включаючи мультимедійні вкладення та дані профілю."
+          noop: Нічого
           silence: Глушення
           suspend: Блокування
-        title: Нове доменне блокування
+        title: Нове блокування домену
       reject_media: Заборонити медіаконтент
-      reject_media_hint: Видаляє медіаконтент, збережений локально, і забороняє його завантаження у майбутньому. Не має значення у випадку блокування.
-      severities:
-        silence: Глушення
-        suspend: Блокування
-      severity: Суворість
+      reject_media_hint: Видаляє медіаконтент, збережений локально, і забороняє його завантаження у майбутньому. Не має значення у випадку блокування
       show:
         affected_accounts:
           few: Впливає на %{count} акаунти у базі даних
@@ -95,42 +248,129 @@ uk:
           suspend: Зняти блокування з усіх існуючих акаунтів цього домену
         title: Зняти блокування з домена %{domain}
         undo: Відмінити
-      title: Доменні блокування
       undo: Відмінити
+    email_domain_blocks:
+      add_new: Додати
+      created_msg: Успішно додано поштовий домен до чорного списку
+      delete: Видалити
+      destroyed_msg: Успішно видалено поштовий домен з чорного списку
+      domain: Домен
+      new:
+        create: Додати домен
+        title: Нове доменне блокування домену email
+      title: Чорний список поштових доменів
+    instances:
+      title: Відомі інстанції
+    invites:
+      filter:
+        all: Все
+        available: Доступно
+        expired: Просрочено
+        title: Фільтр
+      title: Запрошення
+    relays:
+      status: Статус
+    report_notes:
+      created_msg: Скарга успішно створена!
+      destroyed_msg: Скарга успішно видалена!
     reports:
+      account:
+        note: примітка
+        report: скарга
+      action_taken_by: Дія виконана
+      are_you_sure: Ви впевнені?
+      assign_to_self: Призначити мені
+      assigned: Призначений модератор
       comment:
         none: Немає
-      id: ID
+      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: Вирішено
-      silence_account: Заглушити акаунт
+      resolved_msg: Скаргу успішно вирішено!
       status: Статус
-      suspend_account: Блокувати акаунт
-      target: Ціль
       title: Скарги
+      unassign: Зняти призначення
       unresolved: Невирішені
-      view: Подивитися
+      updated_at: Оновлені
     settings:
+      activity_api_enabled:
+        desc_html: Кількість локальних постів, активних та нових користувачів у тижневих розрізах
+        title: Публікація агрегованої статистики про активність користувачів
+      bootstrap_timeline_accounts:
+        title: Підписки за замовчуванням для нових користувачів
       contact_information:
         email: Введіть публічний email
         username: Введіть ім'я користувача
+      hero:
+        desc_html: Відображається на головній сторінці. Рекомендована як мінімум 600x100 пікселів. Якщо не вказано, буде використано передпоказ інстанції
+        title: Банер інстанції
+      peers_api_enabled:
+        desc_html: Доменні ім'я, помічені цією інстанцією федисвіту
+        title: Опублікувати список знайдених інстанцій
+      preview_sensitive_media:
+        desc_html: Передпоказ посилання на інших сайтах буде відображати мініатюру навіть якщо медіа відмічене як вразливе
+        title: Показувати вразливе медія у перепоказі OpenGraph
       registrations:
         closed_message:
           desc_html: Відображається на титульній сторінці, коли реєстрація закрита <br>Можна використовувати HTML-теги
           title: Повідомлення про закриту реєстрацію
+        deletion:
+          desc_html: Дозволити будь-кому видаляти свій аккаунт
+          title: Дозволити видалення аккаунтів
+        min_invite_role:
+          disabled: Ніхто
+          title: Дозволити запрошення від
         open:
+          desc_html: Дозволити будь-ком створювати аккаунт
           title: Відкрити реєстрацію
+      show_known_fediverse_at_about_page:
+        desc_html: Коли увімкнено, будуть показані пости з усього відомого федисвіту у передпоказі. Інакше будуть показані локальні пости.
+        title: Показувати доступний федисвіт у передпоказі фіду
+      show_staff_badge:
+        desc_html: Відмічати персонал на сторінці користувачів
+        title: Показувати персонал
       site_description:
         desc_html: Відображається у якості параграфа на титульній сторінці та використовується у якості мета-тега.<br>Можна використовувати HTML-теги, особливо <code>&lt;a&gt;</code> і <code>&lt;em&gt;</code>.
-        title: Опис сайту
+        title: Опис інстанції
       site_description_extended:
         desc_html: Відображається на сторінці додаткової информації<br>Можна використовувати HTML-теги
         title: Розширений опис сайту
+      site_terms:
+        desc_html: |-
+          Ви можене написати власну політику приватності, умови використанні та інші законні штуки<br>
+          Можете використовувати HTML теги
+        title: Особливі умови використання
       site_title: Назва сайту
+      thumbnail:
+        desc_html: Використовується для передпоказів через OpenGraph та API. Бажано розміром 1200х640 пікселів
+        title: Мініатюра інстанції
+      timeline_preview:
+        desc_html: Показувати публічний фід на головній сторінці
+        title: Передпоказ фіду
       title: Налаштування сайту
+    statuses:
+      back_to_account: Назад на сторінку профілю
+      batch:
+        delete: Видалити
+        nsfw_off: Відмітити сприйнятливим
+        nsfw_on: Відмітити несприйнятливим
+      failed_to_execute: Не вийшло
+      media:
+        title: Медіа
+      no_media: Немає медіа
+      title: Статуси аккаунтів
+      with_media: З медіа
     subscriptions:
       callback_url: Callback URL
       confirmed: Підтверджено
@@ -139,24 +379,60 @@ uk:
       title: WebSub
       topic: Тема
     title: Адміністрування
+  admin_mailer:
+    new_report:
+      body: "%{reporter} поскаржився(-лася) %{target}"
+      body_remote: Хтось з домену %{domain} поскаржився(-лася) %{target}
+      subject: Нова скарга до %{instance} (#%{id})
   application_mailer:
-    settings: 'Змінити налаштування email: %{link}'
+    notification_preferences: Змінити налаштування e-mail
+    salutation: "%{name},"
+    settings: 'Змінити налаштування e-mail: %{link}'
     view: 'Перегляд:'
+    view_profile: Показати профіль
+    view_status: Показати статус
   applications:
+    created: Застосунок успішно створений
+    destroyed: Застосунок успішно видалений
     invalid_url: Введена URL неправильна
+    regenerate_token: Перегенерувати токен доступу
+    token_regenerated: Токен доступу успішне перегенеровано
+    warning: Будьте дуже обережні з цими даними. Ніколи не діліться ними ні з ким!
+    your_token: Ваш токен доступу
   auth:
+    agreement_html: Реєструючись, ви погоджуєтеся виконувати <a href="%{rules_path}">правила інстанції</a> та <a href="%{terms_path}">наші умови використання</a>.
+    change_password: Пароль
+    confirm_email: Підтвердьте e-mail адресу
+    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: або
+    or_log_in_with: Або увійдіть з
+    providers:
+      cas: CAS
+      saml: SAML
     register: Зареєструватися
+    register_elsewhere: Зареєструватися на іншому сервері
     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:
@@ -164,46 +440,77 @@ uk:
       about_x_months: "%{count}міс"
       about_x_years: "%{count}Ñ€"
       almost_x_years: "%{count}Ñ€"
-      half_a_minute: Тільки що
+      half_a_minute: Щойно
       less_than_x_minutes: "%{count}хв"
-      less_than_x_seconds: Тільки що
+      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: Це <strong>безвідворотно і назавжди</strong> видалить контент з вашого аккаунту та деактивує його. Ваше ім'я користувача буде залишатися зарезервованим для уникнення вашої деперсоналізації.
+    proceed: Видалити аккаунт
+    success_msg: Ваш аккаунт було успішно видалено
+    warning_html: Ми можемо гарантувати видалення контенти <b>лише з цього сайту</b>. Контент, що був поширений залишає сліди. Сервери, що є офлайн та ті, що відписалися від наших оновлень не запишуть змін до своїх баз даних.
+    warning_title: Про доступність поширеного контенту
   errors:
     '403': У Вас немає доступу до перегляду даної сторінки.
     '404': Сторінка, яку Ви шукали, не існує.
     '410': Сторінка, яку Ви шукали, більше не існує.
     '422':
       content: Перевірка безпеки не вдалася. Можливо, Ви блокуєте cookies?
-      title: Перевірка безпеки не вдалася.
+      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: CSV
     follows: Підписки
     mutes: Список глушення
     storage: Ваш медіаконтент
+  filters:
+    contexts:
+      home: Ваш фід
+      notifications: Сповіщення
+      public: Публічний фід
+      thread: Повідомлення
+    edit:
+      title: Редагувати фільтр
+    errors:
+      invalid_context: Контекст неправильний або не був наданий
+      invalid_irreversible: Незворотне фільтрування працює тільки в контексті свого фіду або сповіщень
+    index:
+      delete: Видалити
+      title: Фільтри
+    new:
+      title: Додати фільтр
   followers:
     domain: Домен
-    explanation_html: Якщо Ви хочете бути впевнені в приватності Ваших статусів, Ви повинні мати чітке уявлення про те, хто на Вас підписаний. <strong>Ваші приватні статусі відправляються усім інстанціям, на яких у Вас є підписники</strong>. Рекомендуємо видалити з підписників користувачів інстанцій, адміністрації чи програмному забезпеченню яких Ви не довіряєте.
+    explanation_html: Якщо Ви хочете бути впевнені в приватності Ваших статусів, Ви повинні мати чітке уявлення про те, хто на Вас підписаний. <strong>Ваші приватні статусі відправляються усім сайтам, на яких у Вас є підписники</strong>. Рекомендуємо видалити з підписників користувачів інстанцій, адміністрації чи програмному забезпеченню яких Ви не довіряєте.
     followers_count: Кількість підписників
     lock_link: Закрийте акаунт
     purge: Видалити з підписників
-    success:
-      one: У процесі м'якого блокування підписників з одного домену...
-      other: У процесі м'якого блокування підписників з %{count} доменів...
+    success: У процесі м'якого блокування підписників з %{count} доменів...
     true_privacy_html: Будь ласка, помітьте, що <strong>справжняя конфіденційність може бути досягнена тільки за допомогою end-to-end шифрування</strong>.
     unlocked_warning_html: Хто завгодно може підписатися на Вас та отримати доступ до перегляду Ваших приватних статусів. %{lock_link}, щоб отримати можливість роздивлятися та вручну підтверджувати запити щодо підписки.
     unlocked_warning_title: Ваш аккаунт не закритий для підписки
   generic:
     changes_saved_msg: Зміни успішно збережені!
-    powered_by: працює на %{link}
     save_changes: Зберегти зміни
-    validation_errors:
-      one: Щось тут не так! Будь ласка, ознайомтеся з помилкою нижче
-      other: Щось тут не так! Будь ласка, ознайомтеся з %{count} помилками нижче
+    validation_errors: Щось тут не так! Будь ласка, ознайомтеся з %{count} помилками нижче
   imports:
     preface: Вы можете завантажити деякі дані, наприклад, списки людей, на яких Ви підписані чи яких блокуєте, в Ваш акаунт на цій інстанції з файлів, експортованих з іншої інстанції.
     success: Ваші дані були успішно загружені та будуть оброблені в найближчий момент
@@ -212,103 +519,243 @@ uk:
       following: Підписки
       muting: Список глушення
     upload: Завантажити
-  landing_strip_html: "<strong>%{name}</strong> - користувач на %{link_to_root_path}. Ви можете підписатися на нього/неї та спілкуватися з ним/нею, якщо у Вас є акаунт на будь-якій інстанції загальної мережі."
-  landing_strip_signup_html: Якщо його у Вас немає, Ви можете <a href="%{sign_up_path}">зареєструватися тут</a>.
+  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: "%{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:
-      body: 'Коротко про пропущене Вами на %{instance} з Вашого останнього входу %{since}:'
+      action: Показати усі сповіщення
+      body: Коротко про пропущене вами з Вашого останнього входу %{since}
       mention: "%{name} згадав(-ла) Вас в:"
       new_followers_summary:
         few: У Вас з'явилось %{count} нових підписники! Чудово!
         many: У Вас з'явилось %{count} нових підписників! Чудово!
-        one: У Вас з'явився новий підписник! Ура!
-        other: У Вас з'явилось %{count} нових підписників! Чудово!
+        one: Також, у Вас з'явився новий підписник, коли ви були відсутні! Ура!
+        other: Також, у Вас з'явилось %{count} нових підписників, поки ви були відсутні! Чудово!
       subject:
         few: "%{count} нові сповіщення з Вашого останнього входу \U0001F418"
         many: "%{count} нових сповіщень з Вашого останнього входу \U0001F418"
         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:
-      body: 'Ви були згадані %{name} в:'
-      subject: Ви були згадані %{name}
+      action: Відповісти
+      body: 'Вас згадав(-ла) %{name} в:'
+      subject: Вас згадав(-ла) %{name}
+      title: Нова згадка
     reblog:
       body: 'Ваш статус було передмухнуто %{name}:'
       subject: "%{name} передмухнув ваш статус"
+      title: Нове передмухування
   number:
     human:
       decimal_units:
         format: "%n%u"
         units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
+          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 для Вашого аккаунта закінчився неудачою
-    proceed: Продовжити підписку
+    acct: Введіть username@domain, яким ви хочете підписатися
+    missing_resource: Пошук потрібного перенаправлення URL для Вашого аккаунта закінчився невдачею
+    no_account_html: Не маєте аккаунту? Не біда, ви можете <a href='%{sign_up_path}' target='_blank'>зареєструватися</a>
+    proceed: Перейти до підписки
     prompt: 'Ви хочете підписатися на:'
+  remote_unfollow:
+    error: Помилка
+    title: Заголовок
+    unfollowed: Відписані
+  sessions:
+    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: Сесії
   settings:
-    authorized_apps: Авторизованные приложения
-    back: Назад в Mastodon
+    authorized_apps: Авторизовані застосунки
+    back: Назад у Mastodon
+    delete: Видалення аккаунту
+    development: Розробка
     edit_profile: Редагувати профіль
     export: Експорт даних
     followers: Авторизовані підписники
     import: Імпорт
+    migrate: Міграція акаунту
+    notifications: Сповіщення
     preferences: Налаштування
     settings: Опції
-    two_factor_authentication: Двофакторна аутентифікація
+    two_factor_authentication: Двофакторна авторизація
+    your_apps: Ваші затосунки
   statuses:
-    open_in_web: Відкрити в WWW
+    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})
+    pin_errors:
+      limit: Ви вже закріпили максимальну кількість постів
+      ownership: Не можна закріпити чужий пост
+      private: Не можна закріпити непублічний пост
+      reblog: Не можна закріпити просунутий пост
     show_more: Детальніше
+    title: '%{name}: "%{quote}"'
     visibilities:
       private: Для підписників
-      private_long: Показувати тількои підписникам
+      private_long: Показувати тільки підписникам
       public: Для всіх
       public_long: Показувати всім
-      unlisted: Приховувати зі стріок
+      unlisted: Приховувати зі стрічок
       unlisted_long: Показувати всім, але не відображати в публічних стрічках
   stream_entries:
-    click_to_show: Показати
+    pinned: Закріплений пост
     reblogged: передмухнув(-ла)
-    sensitive_content: Непристойний контент
+    sensitive_content: Несприйнятливий контент
+  terms:
+    title: Умови використання та Політика приватності %{instance}
+  themes:
+    contrast: Висока контрасність
+    default: Mastodon
+    mastodon-light: Mastodon (світла)
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
   two_factor_authentication:
-    code_hint: Для підтверждення введіть код, згенерований додатком аутентифікатора
+    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: Коди відновлення дозволяють повернути доступ до акаунту у випадку втрати телефону. Якщо Ви втратили Ваші коди відновлення, Ви можете знову згенерувати їх тут. Ваші старі коди відновлення будуть анульовані.
+    instructions_html: "<strong>Відскануйте цей QR-код за допомогою Google Authenticator чи іншого TOTP-застосунку на Вашому телефоні</strong>. З цього моменту він буде генерувати коди, які буде необхідно ввести для входу."
+    lost_recovery_codes: Коди відновлення дозволяють повернути доступ до акаунту у випадку втрати телефону. Якщо Ви втратили Ваші коди відновлення, Ви можете знову згенерувати їх тут. Тоді ваші старі коди відновлення будуть анульовані.
     manual_instructions: 'Якщо Ви не можете відсканувати QR-код та хочете ввести його вручну, секрет представлений тут відкритим текстом:'
+    recovery_codes: Запасні коди відновлення
     recovery_codes_regenerated: Коди відновлення успішно згенеровані
-    recovery_instructions_html: У випадку втрати доступу до Вашого телефона Ви можете використати один з кодів відновлення, вказаних нижче, щоб повернути доступ до акаунту. Тримайте коди відновлення у безпеці, наприклад, роздрукувавши їх та тримаючи їх з іншими важливими документами.
+    recovery_instructions_html: У випадку втрати доступу до вашого телефону ви можете використати один з кодів відновлення, вказаних нижче, щоб повернути доступ до акаунту. Тримайте коди відновлення у безпеці, наприклад, роздруйте їх та зберігайте їх з іншими важливими документами.
     setup: Налаштувати
-    wrong_code: Введений код неправильний! Чи правильно встановлені серверний час та час пристрою?
+    wrong_code: Введений код неправильний! Чи правильно встановлений час на сервері та пристрої?
+  user_mailer:
+    backup_ready:
+      explanation: Ви зробили запит на повний архів вашого аккаунту Mastodon. Він вже готовий для завантаження!
+      subject: Ваш архів готовий до завантаження
+      title: Винесення архіву
+    welcome:
+      edit_profile_action: Налаштувати профіль
+      edit_profile_step: Ви можете налаштувати профіль під себе завантаживши аватар, шпалери, змінивши відображуване ім'я тощо. Якщо ви захочете переглядати нових підписників до того, як вони зможуть підписатися на вас, ви можете заблокувати свій аккаунт.
+      explanation: Ось декілька порад для початку
+      final_action: Почати постити
+      final_step: 'Почність постити! Навіть не підписавшись на вас, інші зможуть побачити ваші пости, наприкоал, у локальному фіді та у хештеґах. Якщо ви хочете представитися, можете скористатися хештеґом #introductions.'
+      full_handle: Ваше звернення
+      full_handle_hint: Те, що ви хочете сказати друзям, щоб вони могли написати вам або підписатися з інших сайтів.
+      review_preferences_action: Змінити налаштування
+      review_preferences_step: Переконайтеся у тому, що ви налаштували все необхідне, як от які e-mail повідомлення ви хочете отримувати, або який рівень приватності ви хочете встановити вашим постам за замовчуванням. Якщо хочете, ви можете увімкнути автоматичне програвання GIF анімацій.
+      subject: Ласкаво просимо до Mastodon
+      tip_federated_timeline: Федерований фід є широким поглядом на мережу Mastodon. Але він включає лише людей, на яких підписані ваші сусіди по сайту, тому він не є повним.
+      tip_following: Ви автоматично підписані на адміністратора(-ів) сервера. Для того, щоб знайти ще цікавих людей, дослідіть локальний та федерований фіди.
+      tip_local_timeline: Локальний фід - це погляд згори на людей на %{instance}. Це ваші прямі сусіди!
+      tip_mobile_webapp: Якщо ваш мобільний браузер пропонує вам додати Mastodon на робочий стіл, ви можете отримувати push-сповіщення. Все може виглядати як нативний застосунок у багатьох речах.
+      tips: Поради
+      title: Ласкаво просимо, %{name}!
   users:
-    invalid_email: Введений email неправильний
+    invalid_email: Введена адреса e-mail неправильна
     invalid_otp_token: Введено неправильний код
+    otp_lost_help_html: Якщо ви втратили доступ до обох, ви можете отримати доступ з %{email}
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 59858534d4954c2016537c97e4f3389af3ac75df..076bdb17e26fb3e98fe4d79341edc621137833e1 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -5,13 +5,13 @@ zh-CN:
     about_mastodon_html: Mastodon(长毛象)是一个建立在开放式网络协议和自由、开源软件之上的社交网络,有着类似于电子邮件的分布式设计。
     about_this: 关于本实例
     administered_by: 本实例的管理员:
+    api: API
+    apps: 移动应用
     closed_registrations: 这个实例目前没有开放注册。不过,你可以前往其他实例注册一个帐户,同样可以加入到这个网络中哦!
     contact: 联系方式
     contact_missing: 未设定
     contact_unavailable: 未公开
-    description_headline: 关于 %{domain}
-    domain_count_after: 个其它实例
-    domain_count_before: 现已接入
+    documentation: 文档
     extended_description_html: |
       <h3>这里可以写一些规定</h3>
       <p>本站尚未设置详细介绍。</p>
@@ -28,25 +28,32 @@ zh-CN:
     hosted_on: 一个在 %{domain} 上运行的 Mastodon 实例
     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: 关注者
+    followers:
+      one: 关注者
+      other: 关注者
     following: 正在关注
+    joined: 加入于 %{date}
     media: 媒体
     moved_html: "%{name} 已经迁移到 %{new_profile_link}:"
-    network_hidden: 此信息不可用。
+    network_hidden: 此信息不可用
     nothing_here: 这里神马都没有!
     people_followed_by: "%{name} 关注的人"
     people_who_follow: 关注 %{name} 的人
-    posts: 嘟文
+    posts:
+      one: 嘟文
+      other: 嘟文
+    posts_tab_heading: 嘟文
     posts_with_replies: 嘟文和回复
-    remote_follow: 跨站关注
     reserved_username: 此用户名已被保留
     roles:
       admin: 管理员
@@ -107,10 +114,6 @@ zh-CN:
       most_recent_activity: 最后一次活跃的时间
       most_recent_ip: 最后一次活跃的 IP 地址
       not_subscribed: 未订阅
-      order:
-        alphabetic: 按字母
-        most_recent: 按时间
-        title: 排序
       outbox_url: 发件箱(Outbox)URL
       perform_full_suspension: 永久封禁
       profile_url: 个人资料页面 URL
@@ -138,7 +141,6 @@ zh-CN:
       shared_inbox_url: 公用收件箱(Shared Inbox)URL
       show:
         created_reports: 这个帐户提交的举报
-        report: 个举报
         targeted_reports: 针对这个帐户的举报
       silence: 隐藏
       statuses: 嘟文
@@ -180,6 +182,7 @@ zh-CN:
         unsuspend_account: "%{name} 解除了用户 %{target} 的封禁状态"
         update_custom_emoji: "%{name} 更新了自定义表情 %{target}"
         update_status: "%{name} 刷新了 %{target} 的嘟文"
+      deleted_status: "(嘟文已删除)"
       title: 运营日志
     custom_emojis:
       by_domain: 域名
@@ -206,6 +209,27 @@ zh-CN:
       update_failed_msg: 表情更新失败!
       updated_msg: 表情更新成功!
       upload: 上传新表情
+    dashboard:
+      backlog: 未处理任务数
+      config: 服务器配置
+      feature_deletions: 帐户删除
+      feature_invites: 邀请链接
+      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: 正在进行域名屏蔽
@@ -222,19 +246,15 @@ zh-CN:
         title: 添加域名屏蔽
       reject_media: 拒绝接收媒体文件
       reject_media_hint: 删除本地已缓存的媒体文件,并且不再接收来自该域名的任何媒体文件。此选项不影响封禁
-      severities:
-        noop: æ— 
-        silence: 自动隐藏
-        suspend: 自动封禁
-      severity: 屏蔽级别
       show:
-        affected_accounts: 将会影响到数据库中的 %{count} 个帐户
+        affected_accounts:
+          one: 将会影响到数据库中的 1 个帐户
+          other: 将会影响到数据库中的 %{count} 个帐户
         retroactive:
           silence: 对此域名的所有帐户解除隐藏
           suspend: 对此域名的所有帐户解除封禁
         title: 撤销对 %{domain} 的域名屏蔽
         undo: 撤销
-      title: 域名屏蔽
       undo: 撤销
     email_domain_blocks:
       add_new: 添加新条目
@@ -247,18 +267,25 @@ zh-CN:
         title: 添加电子邮件域名屏蔽
       title: 电子邮件域名屏蔽
     instances:
-      account_count: 已知帐户
-      domain_name: 域名
-      reset: 重置
-      search: 搜索
       title: 已知实例
     invites:
+      deactivate_all: 撤销所有邀请链接
       filter:
         all: 全部
         available: 可用
         expired: 已失效
         title: 筛选
       title: 邀请用户
+    relays:
+      add_new: 添加新的中继
+      description_html: "<strong>同步中继</strong>是一种中间服务器,各实例可以通过订阅中继和向中继推送信息的方式来大量交换公开嘟文。<strong>它可以帮助中小型实例发现网络中的内容</strong>,而无需本地用户手动关注其他远程实例上的用户。"
+      enable_hint: 启用此功能后,你的实例会订阅此中继的所有公开嘟文,并同时向其推送本服务器的公开嘟文。
+      inbox_url: 中继 URL
+      pending: 等待中继确认
+      save_and_enable: 保存并启用
+      setup: 设置中继连接
+      status: 状态
+      title: 中继
     report_notes:
       created_msg: 举报记录建立成功!
       destroyed_msg: 举报记录删除成功!
@@ -273,7 +300,6 @@ zh-CN:
       comment:
         none: 没有
       created_at: 举报时间
-      id: ID
       mark_as_resolved: 标记为“已处理”
       mark_as_unresolved: 标记为“未处理”
       notes:
@@ -281,23 +307,18 @@ zh-CN:
         create_and_resolve: 添加记录并标记为“已处理”
         create_and_unresolve: 添加记录并重开
         delete: 删除
-        placeholder: 描述已经执行的操作,或其他任何相关的跟进情况
+        placeholder: 描述已经执行的操作,或其他任何相关的跟进情况…
       reopen: 重开举报
       report: '举报 #%{id}'
-      report_contents: 内容
       reported_account: 举报用户
       reported_by: 举报人
       resolved: 已处理
       resolved_msg: 举报处理成功!
-      silence_account: 隐藏用户
       status: 状态
-      suspend_account: 封禁用户
-      target: 被举报人
       title: 举报
       unassign: 取消接管
       unresolved: 未处理
       updated_at: æ›´æ–°æ—¶é—´
-      view: 查看
     settings:
       activity_api_enabled:
         desc_html: 本站用户发布的嘟文数,以及本站的活跃用户数和一周内新用户数
@@ -308,12 +329,18 @@ zh-CN:
       contact_information:
         email: 用于联系的公开电子邮件地址
         username: 用于联系的公开用户名
+      custom_css:
+        desc_html: 通过 CSS 代码调整所有页面的显示效果
+        title: 自定义 CSS
       hero:
         desc_html: 用于在首页展示。推荐分辨率 600×100px 以上。未指定的情况下将默认使用本站缩略图
         title: 主题图片
       peers_api_enabled:
         desc_html: 截至目前本实例在网络中已发现的域名
         title: 公开已知实例的列表
+      preview_sensitive_media:
+        desc_html: 始终在站外链接预览中展示缩略图,无论媒体内容是否标记为敏感
+        title: 在 OpenGraph 预览中显示敏感媒体内容
       registrations:
         closed_message:
           desc_html: 本站关闭注册期间的提示信息。可以使用 HTML 标签
@@ -328,7 +355,7 @@ zh-CN:
           desc_html: 允许所有人建立帐户
           title: 开放注册
       show_known_fediverse_at_about_page:
-        desc_html: 启用此选项将会在预览中显示来自已知实例的嘟文,否则只会显示本站时间轴的内容
+        desc_html: 启用此选项将会在预览中显示来自已知实例的嘟文,否则只会显示本站时间轴的内容.
         title: 在时间轴预览中显示已知实例
       show_staff_badge:
         desc_html: 在个人资料页上显示管理人员标志
@@ -458,7 +485,7 @@ zh-CN:
     '500':
       content: 抱歉,我们的后台出错了。
       title: 这个页面有问题
-    noscript_html: 使用 Mastodon 网页版应用需要启用 JavaScript。你也可以选择适用于你的平台的 <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">Mastodon 应用</a>。
+    noscript_html: 使用 Mastodon 网页版应用需要启用 JavaScript。你也可以选择适用于你的平台的 <a href="%{apps_path}">Mastodon 应用</a>。
   exports:
     archive_takeout:
       date: 日期
@@ -472,6 +499,21 @@ zh-CN:
     follows: 关注的用户
     mutes: 隐藏的用户
     storage: 媒体文件存储
+  filters:
+    contexts:
+      home: 主页时间轴
+      notifications: 通知
+      public: 公共时间轴
+      thread: 对话
+    edit:
+      title: 编辑过滤器
+    errors:
+      invalid_irreversible: 此功能只适用于主页时间轴或通知
+    index:
+      delete: 删除
+      title: 过滤器
+    new:
+      title: 添加新的过滤器
   followers:
     domain: 域名
     explanation_html: 为保证你的嘟文的隐私安全,你应当经常检查你的关注者列表。<strong>受保护的嘟文将会发送到所有关注者所在的实例上</strong>。有些实例使用的软件代码或其管理员可能不会尊重你的隐私设置,因此你应当复查一下关注者列表,并移除那些你无法信任的关注者。
@@ -484,7 +526,6 @@ zh-CN:
     unlocked_warning_title: 你的帐户未受到保护
   generic:
     changes_saved_msg: 更改保存成功!
-    powered_by: 基于 %{link} 构建
     save_changes: 保存更改
     validation_errors:
       one: 出错啦!检查一下下面出错的地方吧
@@ -511,15 +552,15 @@ zh-CN:
     expires_in_prompt: 永不过期
     generate: 生成邀请链接
     invited_by: 你的邀请人是:
-    max_uses: "%{count} 次"
+    max_uses:
+      one: 1 次
+      other: "%{count} 次"
     max_uses_prompt: 无限制
     prompt: 生成分享链接,邀请他人在本实例注册
     table:
       expires_at: 失效时间
       uses: 已使用次数
     title: 邀请用户
-  landing_strip_html: "<strong>%{name}</strong> 是一位来自 %{link_to_root_path} 的用户。如果你想关注他们或者与他们互动,你需要在任意一个 Mastodon 实例或与其兼容的网站上拥有一个帐户。"
-  landing_strip_signup_html: 还没有这种帐户?你可以<a href="%{sign_up_path}">在本站注册一个</a>。
   lists:
     errors:
       limit: 你所建立的列表数量已经达到上限
@@ -591,6 +632,7 @@ zh-CN:
   remote_follow:
     acct: 请输入你的“用户名@实例域名”
     missing_resource: 无法确定你的帐户的跳转 URL
+    no_account_html: 还没有帐号?你可以<a href='%{sign_up_path}' target='_blank'>注册一个</a>
     proceed: 确认关注
     prompt: 你正准备关注:
   remote_unfollow:
@@ -656,8 +698,12 @@ zh-CN:
   statuses:
     attached:
       description: 附加媒体:%{attached}
-      image: "%{count} 张图片"
-      video: "%{count} 个视频"
+      image:
+        one: "%{count} 张图片"
+        other: "%{count} 张图片"
+      video:
+        one: "%{count} 段视频"
+        other: "%{count} 段视频"
     boosted_from_html: 转嘟自 %{acct_link}
     content_warning: 内容警告:%{warning}
     disallowed_hashtags:
@@ -681,7 +727,6 @@ zh-CN:
       unlisted: 不公开
       unlisted_long: 所有人可见,但不会出现在公共时间轴上
   stream_entries:
-    click_to_show: 点击显示
     pinned: 置顶嘟文
     reblogged: 转嘟
     sensitive_content: 敏感内容
@@ -696,7 +741,7 @@ zh-CN:
       default: "%Y年%-m月%d日 %H:%M"
   two_factor_authentication:
     code_hint: 输入认证器生成的代码以确认操作
-    description_html: 启用<strong>双重认证</strong>后,你需要输入手机认证器生成的代码才能登录
+    description_html: 启用<strong>双重认证</strong>后,你需要输入手机认证器生成的代码才能登录.
     disable: 停用
     enable: 启用
     enabled: 双重认证已启用
@@ -726,7 +771,6 @@ zh-CN:
       review_preferences_action: 更改首选项
       review_preferences_step: 记得调整你的偏好设置,比如你想接收什么类型的邮件,或者你想把你的嘟文可见范围默认设置为什么级别。如果你没有晕动病的话,考虑一下启用“自动播放 GIF 动画”这个选项吧。
       subject: 欢迎来到 Mastodon
-      tip_bridge_html: 如果你刚从 Twitter 来到这里,你可以在<a href="%{bridge_url}">桥梁站(bridge app)</a>上寻找你的朋友。当然,前提是他们也登录了桥梁站!
       tip_federated_timeline: 跨站公共时间轴可以让你一窥更广阔的 Mastodon 网络。不过,由于它只显示你的邻居们所订阅的内容,所以并不是全部。
       tip_following: 默认情况下,你会自动关注你所在实例的管理员。想结交更多有趣的人的话,记得多逛逛本站时间轴和跨站公共时间轴哦。
       tip_local_timeline: 本站时间轴可以让你一窥 %{instance} 上的用户。他们就是离你最近的邻居!
diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml
index ceeeb948caff83e46ac5e4199a7a81417ad67fab..97adfe84d3625baa9ba149146286faaba252831b 100644
--- a/config/locales/zh-HK.yml
+++ b/config/locales/zh-HK.yml
@@ -9,9 +9,6 @@ zh-HK:
     contact: 聯絡
     contact_missing: 未設定
     contact_unavailable: 未公開
-    description_headline: 甚麼是 %{domain} ?
-    domain_count_after: 個其他服務站
-    domain_count_before: 已連接至
     extended_description_html: |
       <h3>這裡可以寫一些網站規則</h3>
       <p>本站未有詳細介紹</p>
@@ -46,7 +43,6 @@ zh-HK:
     people_who_follow: 關注 %{name} 的人
     posts: 文章
     posts_with_replies: 文章和回覆
-    remote_follow: 跨站關注
     reserved_username: 此用戶名已被保留
     roles:
       admin: 管理員
@@ -107,10 +103,6 @@ zh-HK:
       most_recent_activity: 最新活動
       most_recent_ip: 最新 IP 位域
       not_subscribed: 未訂閱
-      order:
-        alphabetic: 按字母
-        most_recent: 按時間
-        title: 排序
       outbox_url: 寄件箱(Outbox)URL
       perform_full_suspension: 完全停權
       profile_url: 個人檔案 URL
@@ -138,7 +130,6 @@ zh-HK:
       shared_inbox_url: 公共收件箱(Shared Inbox)URL
       show:
         created_reports: 此用戶所提舉報的紀錄
-        report: 舉報
         targeted_reports: 此用戶被舉報的紀錄
       silence: 靜音
       statuses: 文章
@@ -221,22 +212,14 @@ zh-HK:
           suspend: 自動刪除
         title: 新增域名阻隔
       reject_media: 拒絕媒體檔案
-      reject_media_hint: 刪除本地緩存的媒體檔案,再也不在未來下載這個站點的檔案。和自動刪除無關。
-      severities:
-        noop: ç„¡
-        silence: 自動靜音
-        suspend: 自動刪除
-      severity: 阻隔分級
+      reject_media_hint: 刪除本地緩存的媒體檔案,再也不在未來下載這個站點的檔案。和自動刪除無關
       show:
-        affected_accounts:
-          one: 資料庫中有 %{count} 個用戶受影響
-          other: 資料庫中有%{count}個用戶受影響
+        affected_accounts: 資料庫中有%{count}個用戶受影響
         retroactive:
           silence: 對此域名的所有用戶取消靜音
           suspend: 對此域名的所有用戶取消除名
         title: 撤銷 %{domain} 的域名阻隔
         undo: 撤銷
-      title: 域名阻隔
       undo: 撤銷
     email_domain_blocks:
       add_new: 加入新項目
@@ -249,10 +232,6 @@ zh-HK:
         title: 新增電郵網域阻隔
       title: 電郵網域阻隔
     instances:
-      account_count: 已知帳號
-      domain_name: 域名
-      reset: 重設
-      search: 搜索
       title: 已知服務站
     invites:
       filter:
@@ -275,7 +254,6 @@ zh-HK:
       comment:
         none: 沒有
       created_at: 日期
-      id: ID
       mark_as_resolved: 標示為「已處理」
       mark_as_unresolved: 標示為「未處理」
       notes:
@@ -286,20 +264,15 @@ zh-HK:
         placeholder: 記錄已執行的動作,或其他相關的更新……
       reopen: 重開舉報
       report: '舉報 #%{id}'
-      report_contents: 舉報內容
       reported_account: 舉報用戶
       reported_by: 舉報者
       resolved: 已處理
       resolved_msg: 舉報已處理。
-      silence_account: 將用戶靜音
       status: 狀態
-      suspend_account: 將用戶停權
-      target: 對象
       title: 舉報
       unassign: 取消指派
       unresolved: 未處理
       updated_at: æ›´æ–°
-      view: 檢視
     settings:
       activity_api_enabled:
         desc_html: 本站用戶發佈的文章,以及本站的活躍用戶和一週內新用戶數
@@ -311,7 +284,7 @@ zh-HK:
         email: 輸入一個公開的電郵地址
         username: 輸入用戶名稱
       hero:
-        desc_html: 在首頁顯示。推薦最小 600x100px。如果留空,就會默認為服務站縮圖。
+        desc_html: 在首頁顯示。推薦最小 600x100px。如果留空,就會默認為服務站縮圖
         title: 主題圖片
       peers_api_enabled:
         desc_html: 現時本服務站在網絡中已發現的域名
@@ -460,7 +433,7 @@ zh-HK:
     '500':
       content: 抱歉,我們的後台出錯了。
       title: 這個頁面有問題
-    noscript_html: 使用 Mastodon 網頁版應用需要啟用 JavaScript。你也可以選擇適用於你的平台的 <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">Mastodon 應用</a>。
+    noscript_html: 使用 Mastodon 網頁版應用需要啟用 JavaScript。你也可以選擇適用於你的平台的 <a href="%{apps_path}">Mastodon 應用</a>。
   exports:
     archive_takeout:
       date: 日期
@@ -488,7 +461,6 @@ zh-HK:
     unlocked_warning_title: 你的用戶目前為「公共」
   generic:
     changes_saved_msg: 已成功儲存修改。
-    powered_by: 網站由 %{link} 開發
     save_changes: 儲存修改
     validation_errors:
       one: 提交的資料有問題
@@ -524,8 +496,6 @@ zh-HK:
       expires_at: 失效時間
       uses: 已使用次數
     title: 邀請用戶
-  landing_strip_html: "<strong>%{name}</strong> 是一個在 %{link_to_root_path} 的用戶。只要你有任何 Mastodon 服務站、或者聯盟網站的用戶,便可以跨站關注此站用戶,或者與他們互動。"
-  landing_strip_signup_html: 如果你沒有這類用戶,歡迎在<a href="%{sign_up_path}">此處登記</a>。
   lists:
     errors:
       limit: 你所建立的列表數量已經達到上限
@@ -543,7 +513,7 @@ zh-HK:
   notification_mailer:
     digest:
       action: 查看所有通知
-      body: 這是自從你在%{since}使用%{instance}以後,你錯失了的訊息︰
+      body: 這是自從你在%{since}使用以後,你錯失了的訊息︰
       mention: "%{name} 在此提及了你︰"
       new_followers_summary:
         one: 你新獲得了 1 位關注者了!恭喜!
@@ -692,7 +662,6 @@ zh-HK:
       unlisted: 公開,但不在公共時間軸顯示
       unlisted_long: 所有人都能看到,但不在公共時間軸(本站時間軸、跨站時間軸)顯示
   stream_entries:
-    click_to_show: 點擊顯示
     pinned: 置頂文章
     reblogged: 轉推
     sensitive_content: 敏感內容
@@ -737,7 +706,6 @@ zh-HK:
       review_preferences_action: 更改首選項
       review_preferences_step: 記得調整你的偏好設置,比如你想接收什麼類型的郵件,或者你想把你的文章可見範圍默認設定為什麼級別。如果你沒有暈車的話,考慮一下啟用「自動播放 GIF 動畫」這個選項吧。
       subject: 歡迎來到 Mastodon
-      tip_bridge_html: 如果你剛從 Twitter 來到這裡,你可以在<a href="%{bridge_url}">橋樑站(bridge app)</a>上尋找你的朋友。當然,前提是他們也登錄了橋樑站!
       tip_federated_timeline: 跨站公共時間軸可以讓你一窺更廣闊的 Mastodon 網絡。不過,由於它只顯示你的鄰居們所訂閱的內容,所以並不是全部。
       tip_following: 默認情況下,你會自動關注你所在服務站的管理員。想結交更多有趣的人的話,記得多逛逛本站時間軸和跨站公共時間軸哦。
       tip_local_timeline: 本站時間軸可以讓你一窺 %{instance} 上的用戶。他們就是離你最近的鄰居!
@@ -747,6 +715,6 @@ zh-HK:
   users:
     invalid_email: 電郵地址格式不正確
     invalid_otp_token: 雙重認證確認碼不正確
-    otp_lost_help_html: 如果你無法訪問這兩者,可以通過 %{email} 與我們聯繫。
+    otp_lost_help_html: 如果你無法訪問這兩者,可以通過 %{email} 與我們聯繫
     seamless_external_login: 由於你是從外部系統登入,所以不能設定密碼和電郵。
     signed_in_as: 目前登入的帳戶:
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index e2b376a3f9f8c728de1cfe109c3ef1209441caee..f4bda0f348fb12dbfef7333bc5222ee5967f6e62 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -5,13 +5,13 @@ zh-TW:
     about_mastodon_html: Mastodon (長毛象)是一個<em>自由、開放原始碼</em>的社群網站。它是一個分散式的服務,避免您的通訊被單一商業機構壟斷操控。請您選擇一家您信任的 Mastodon 站點,在上面建立帳號,然後您就可以和任一 Mastodon 站點上的使用者互通,享受無縫的<em>社群網路</em>交流。
     about_this: 關於本站
     administered_by: 管理者:
+    api: API
+    apps: Mobile apps
     closed_registrations: 本站暫時停止接受註冊。
     contact: 聯絡我們
     contact_missing: 未設定
     contact_unavailable: 未公開
-    description_headline: 關於 %{domain}?
-    domain_count_after: 個站點相連
-    domain_count_before: 與其他
+    documentation: 文件
     extended_description_html: |
       <h3>這裡可以寫一些網站規則</h3>
       <p>本站點未有詳細介紹</p>
@@ -29,9 +29,10 @@ zh-TW:
     learn_more: 了解詳細
     other_instances: 其他站點
     source_code: 原始碼
-    status_count_after: 條嘟嘟
+    status_count_after: 狀態
     status_count_before: 他們共嘟出了
-    user_count_after: 位使用者
+    terms: 使用條款
+    user_count_after: 使用者
     user_count_before: 這裡共註冊有
     what_is_mastodon: 什麼是 Mastodon?
   accounts:
@@ -45,8 +46,8 @@ zh-TW:
     people_followed_by: "%{name} 關注的人"
     people_who_follow: 關注 %{name} 的人
     posts: 嘟文
+    posts_tab_heading: 嘟文
     posts_with_replies: 嘟文與回覆
-    remote_follow: 跨站關注
     reserved_username: 此用戶名已被保留
     roles:
       admin: 管理員
@@ -107,10 +108,6 @@ zh-TW:
       most_recent_activity: 最近活動
       most_recent_ip: 最近 IP 位址
       not_subscribed: 未訂閱
-      order:
-        alphabetic: 按字母
-        most_recent: 按時間
-        title: 排序
       outbox_url: 寄件箱 (Outbox) URL
       perform_full_suspension: 進行停權
       profile_url: 個人檔案 URL
@@ -138,7 +135,6 @@ zh-TW:
       shared_inbox_url: 公共收件箱 (Shared Inbox) URL
       show:
         created_reports: 這個使用者提交的檢舉
-        report: 檢舉
         targeted_reports: 針對這個使用者的檢舉
       silence: 靜音
       statuses: 嘟文
@@ -222,21 +218,13 @@ zh-TW:
         title: 新增封鎖網域
       reject_media: 拒絕媒體檔案
       reject_media_hint: 刪除本地緩存的媒體檔案,並且不再接收來自該網域的任何媒體檔案。與自動封鎖無關
-      severities:
-        noop: ç„¡
-        silence: 自動靜音
-        suspend: 自動封鎖
-      severity: 嚴重度
       show:
-        affected_accounts:
-          one: 資料庫中有一個使用者受到影響
-          other: 資料庫中有%{count}個使用者受影響
+        affected_accounts: 資料庫中有%{count}個使用者受影響
         retroactive:
           silence: 對此網域的所有使用者取消靜音
           suspend: 對此網域的所有使用者取消封鎖
         title: 撤銷 %{domain} 的網域封鎖
         undo: 撤銷
-      title: 網域封鎖
       undo: 撤銷
     email_domain_blocks:
       add_new: 加入新項目
@@ -249,10 +237,6 @@ zh-TW:
         title: 新增E-mail封鎖
       title: E-mail封鎖
     instances:
-      account_count: 已知帳戶
-      domain_name: 網域
-      reset: 重設
-      search: 搜尋
       title: 已知站點
     invites:
       filter:
@@ -275,7 +259,6 @@ zh-TW:
       comment:
         none: ç„¡
       created_at: 日期
-      id: ID
       mark_as_resolved: 標記為「已解決」
       mark_as_unresolved: 標記為「未解決」
       notes:
@@ -286,20 +269,15 @@ zh-TW:
         placeholder: 記錄已執行的動作,或其他相關的更新...
       reopen: 重開檢舉
       report: '檢舉 #%{id}'
-      report_contents: 檢舉內容
       reported_account: 被檢舉使用者
       reported_by: 檢舉人
       resolved: 已解決
       resolved_msg: 檢舉已處理!
-      silence_account: 靜音使用者
       status: 狀態
-      suspend_account: 停權使用者
-      target: 對象
       title: 檢舉
       unassign: 取消指派
       unresolved: 未解決
       updated_at: æ›´æ–°
-      view: 檢視
     settings:
       activity_api_enabled:
         desc_html: 本站使用者發佈的嘟文數量,以及本站的活躍使用者與一週內新使用者數量
@@ -460,7 +438,7 @@ zh-TW:
     '500':
       content: 抱歉,我們的後台出現問題了。
       title: 這個頁面有問題
-    noscript_html: 使用 Mastodon 網頁版應用需要啟用 JavaScript。你也可以選擇適用於你的平台的 <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">Mastodon 應用</a>。
+    noscript_html: 使用 Mastodon 網頁版應用需要啟用 JavaScript。你也可以選擇適用於你的平台的 <a href="%{apps_path}">Mastodon 應用</a>。
   exports:
     archive_takeout:
       date: 日期
@@ -480,19 +458,14 @@ zh-TW:
     followers_count: 關注者數量
     lock_link: 將你的帳戶設定為私人
     purge: 移除關注者
-    success:
-      one: 正準備軟性封鎖 1 個網域的關注者……
-      other: 正準備軟性封鎖 %{count} 個網域的關注者……
+    success: 正準備軟性封鎖 %{count} 個網域的關注者……
     true_privacy_html: 請謹記,唯有<strong>點對點加密方可以真正確保你的隱私</strong>。
     unlocked_warning_html: 任何人都可以在關注你後立即查看非公開的嘟文。只要%{lock_link},你就可以審核並拒絕關注請求。
     unlocked_warning_title: 你的帳戶是公開的
   generic:
     changes_saved_msg: 已成功儲存修改!
-    powered_by: 網站由 %{link} 開發
     save_changes: 儲存修改
-    validation_errors:
-      one: 送出的資料有問題
-      other: 送出的資料有 %{count} 個問題
+    validation_errors: 送出的資料有 %{count} 個問題
   imports:
     preface: 您可以在此匯入您在其他站點所匯出的資料檔,包括關注的使用者、封鎖的使用者名單。
     success: 資料檔上傳成功,正在匯入,請稍候
@@ -515,17 +488,13 @@ zh-TW:
     expires_in_prompt: 永不過期
     generate: 建立邀請連結
     invited_by: 你的邀請人是:
-    max_uses:
-      one: 1 次
-      other: "%{count} 次"
+    max_uses: "%{count} 次"
     max_uses_prompt: 無限制
     prompt: 建立分享連結,邀請他人在本站點註冊
     table:
       expires_at: 失效時間
       uses: 已使用次數
     title: 邀請使用者
-  landing_strip_html: "<strong>%{name}</strong> 是一個在 %{link_to_root_path} 的使用者。只要您有任何 Mastodon 站點、或者聯盟站點的帳戶,便可以跨站關注此站使用者,或者與他們互動。"
-  landing_strip_signup_html: 如果您沒有這些帳戶,歡迎在<a href="%{sign_up_path}">這裡註冊</a>。
   lists:
     errors:
       limit: 你所建立的列表數量已經達到上限
@@ -545,12 +514,8 @@ zh-TW:
       action: 閱覽所有通知
       body: 以下是自%{since}你最後一次登入以來錯過的訊息摘要
       mention: "%{name} 在此提及了你:"
-      new_followers_summary:
-        one: 而且,你不在的時候,有一個人關注你! 耶!
-        other: 而且,你不在的時候,有 %{count} 個人關注你了! 好棒!
-      subject:
-        one: "自從上次登入以來,你收到 1 則新的通知 \U0001F418"
-        other: "自從上次登入以來,你收到 %{count} 則新的通知 \U0001F418"
+      new_followers_summary: 而且,你不在的時候,有 %{count} 個人關注你了! 好棒!
+      subject: "自從上次登入以來,你收到 %{count} 則新的通知 \U0001F418"
       title: 你不在的時候...
     favourite:
       body: '你的嘟文被 %{name} 加入了最愛:'
@@ -656,17 +621,11 @@ zh-TW:
   statuses:
     attached:
       description: 附件: %{attached}
-      image:
-        one: "%{count} 幅圖片"
-        other: "%{count} 幅圖片"
-      video:
-        one: "%{count} 段影片"
-        other: "%{count} 段影片"
+      image: "%{count} 幅圖片"
+      video: "%{count} 段影片"
     boosted_from_html: 轉嘟自 %{acct_link}
     content_warning: 內容警告: %{warning}
-    disallowed_hashtags:
-      one: 包含不允許的標籤: %{tags}
-      other: 包含不允許的標籤: %{tags}
+    disallowed_hashtags: 包含不允許的標籤: %{tags}
     language_detection: 自動偵測語言
     open_in_web: 以網頁開啟
     over_character_limit: 超過了 %{max} 字的限制
@@ -685,7 +644,6 @@ zh-TW:
       unlisted: 公開,但不在公共時間軸顯示
       unlisted_long: 所有人都能看到,但不會出現在公共時間軸上
   stream_entries:
-    click_to_show: 點選顯示
     pinned: 置頂嘟文
     reblogged: 轉嘟
     sensitive_content: 敏感內容
@@ -729,7 +687,6 @@ zh-TW:
       review_preferences_action: 更改偏好設定
       review_preferences_step: 記得調整你的偏好設定,比如你想接收什麼類型的電子郵件,或著你想把你的嘟文可見範圍預設設定什麼級別。如果你沒有暈車的話,考慮一下啟用「自動播放 GIF 動畫」這個選項吧。
       subject: 歡迎來到 Mastodon
-      tip_bridge_html: 如果你剛從 Twitter 來到這裡,你可以在<a href="%{bridge_url}">橋樑站(bridge app)</a>上尋找你的朋友。當然,前提是他們也登入了橋樑站!
       tip_federated_timeline: 跨站公共時間軸可以讓你一窺更廣闊的 Mastodon 網路。不過,由於它們只顯示你的鄰居們所訂閱的內容,所以並不是全部。
       tip_following: 預設情況下,你會自動關注你所在站點的管理員。想結交更多有趣的人的話,記得多逛逛本站時間軸與跨站公共時間軸哦。
       tip_local_timeline: 本站時間軸可以讓你一窺 %{instance} 上的使用者。他們就是離你最近的鄰居!
diff --git a/config/navigation.rb b/config/navigation.rb
index 3f2e913c62903205e297b60e8fb8fc1e9e2dc25d..a9521f956d0293433b9a19084dd79d6f74db76a9 100644
--- a/config/navigation.rb
+++ b/config/navigation.rb
@@ -28,14 +28,16 @@ SimpleNavigation::Configuration.run do |navigation|
       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 :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url, highlights_on: %r{/admin/instances}, if: -> { current_user.admin? }
-      admin.item :domain_blocks, safe_join([fa_icon('lock fw'), t('admin.domain_blocks.title')]), admin_domain_blocks_url, highlights_on: %r{/admin/domain_blocks}, if: -> { current_user.admin? }
+      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? }
     end
 
-    primary.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), proc { current_user.admin? ? edit_admin_settings_url : admin_custom_emojis_url }, if: proc { current_user.staff? } do |admin|
+    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? }
diff --git a/config/puma.rb b/config/puma.rb
index 0397b892048588048784cf95181d61d560f4ed05..1afdb1c6dfbc0900051690c33a2013482398132a 100644
--- a/config/puma.rb
+++ b/config/puma.rb
@@ -1,7 +1,7 @@
 threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i
 threads threads_count, threads_count
 
-if ENV['SOCKET'] then
+if ENV['SOCKET']
   bind 'unix://' + ENV['SOCKET']
 else
   port ENV.fetch('PORT') { 3000 }
@@ -13,7 +13,9 @@ workers     ENV.fetch('WEB_CONCURRENCY') { 2 }
 preload_app!
 
 on_worker_boot do
-  ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
+  ActiveSupport.on_load(:active_record) do
+    ActiveRecord::Base.establish_connection
+  end
 end
 
 plugin :tmp_restart
diff --git a/config/routes.rb b/config/routes.rb
index fd26b4aa74cac3105f5e2c8108fe0d1c64e4e4ca..af49845ccbe77e3abc501abb4fb45eb98f56029b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -21,8 +21,10 @@ 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 'manifest', to: 'manifests#show', defaults: { format: 'json' }
   get 'intent', to: 'intents#show'
+  get 'custom.css', to: 'custom_css#show', as: :custom_css
 
   devise_scope :user do
     get '/invite/:invite_code', to: 'auth/registrations#new', as: :public_invite
@@ -38,6 +40,7 @@ Rails.application.routes.draw do
   }
 
   get '/users/:username', to: redirect('/@%{username}'), constraints: lambda { |req| req.format.nil? || req.format.html? }
+  get '/authorize_follow', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" }
 
   resources :accounts, path: 'users', only: [:show], param: :username do
     resources :stream_entries, path: 'updates', only: [:show] do
@@ -74,6 +77,12 @@ Rails.application.routes.draw do
   get '/@:account_username/:id', to: 'statuses#show', as: :short_account_status
   get '/@:account_username/:id/embed', to: 'statuses#embed', as: :embed_short_account_status
 
+  get  '/interact/:id', to: 'remote_interaction#new', as: :remote_interaction
+  post '/interact/:id', to: 'remote_interaction#create'
+
+  get '/explore', to: 'directories#index', as: :explore
+  get '/explore/:id', to: 'directories#show', as: :explore_hashtag
+
   namespace :settings do
     resource :profile, only: [:show, :update]
     resource :preferences, only: [:show, :update]
@@ -85,6 +94,8 @@ Rails.application.routes.draw do
       resources :follows, only: :index, controller: :following_accounts
       resources :blocks, only: :index, controller: :blocked_accounts
       resources :mutes, only: :index, controller: :muted_accounts
+      resources :lists, only: :index, controller: :lists
+      resources :domain_blocks, only: :index, controller: :blocked_domains
     end
 
     resource :two_factor_authentication, only: [:show, :create, :destroy]
@@ -120,24 +131,42 @@ Rails.application.routes.draw do
 
   # Remote follow
   resource :remote_unfollow, only: [:create]
-  resource :authorize_follow, only: [:show, :create]
+  resource :authorize_interaction, only: [:show, :create]
   resource :share, only: [:show, :create]
 
   namespace :admin do
+    get '/dashboard', to: 'dashboard#index'
+
     resources :subscriptions, only: [:index]
-    resources :domain_blocks, only: [:index, :new, :create, :show, :destroy]
+    resources :domain_blocks, only: [:new, :create, :show, :destroy]
     resources :email_domain_blocks, only: [:index, :new, :create, :destroy]
     resources :action_logs, only: [:index]
+    resources :warning_presets, except: [:new]
     resource :settings, only: [:edit, :update]
-    resources :invites, only: [:index, :create, :destroy]
 
-    resources :instances, only: [:index] do
+    resources :invites, only: [:index, :create, :destroy] do
       collection do
-        post :resubscribe
+        post :deactivate_all
+      end
+    end
+
+    resources :relays, only: [:index, :new, :create, :destroy] do
+      member do
+        post :enable
+        post :disable
       end
     end
 
-    resources :reports, only: [:index, :show, :update] do
+    resources :instances, only: [:index, :show], constraints: { id: /[^\/]+/ }
+
+    resources :reports, only: [:index, :show] do
+      member do
+        post :assign_to_self
+        post :unassign
+        post :reopen
+        post :resolve
+      end
+
       resources :reported_statuses, only: [:create]
     end
 
@@ -148,17 +177,19 @@ Rails.application.routes.draw do
         post :subscribe
         post :unsubscribe
         post :enable
-        post :disable
+        post :unsilence
+        post :unsuspend
         post :redownload
         post :remove_avatar
+        post :remove_header
         post :memorialize
       end
 
       resource :change_email, only: [:show, :update]
       resource :reset, only: [:create]
-      resource :silence, only: [:create, :destroy]
-      resource :suspension, only: [:create, :destroy]
-      resources :statuses, only: [:index, :create, :update, :destroy]
+      resource :action, only: [:new, :create], controller: 'account_actions'
+      resources :statuses, only: [:index, :show, :create, :update, :destroy]
+      resources :followers, only: [:index]
 
       resource :confirmation, only: [:create] do
         collection do
@@ -187,15 +218,16 @@ Rails.application.routes.draw do
     end
 
     resources :account_moderation_notes, only: [:create, :destroy]
-  end
 
-  authenticate :user, lambda { |u| u.admin? } do
-    get '/admin', to: redirect('/admin/settings/edit', status: 302)
+    resources :tags, only: [:index] do
+      member do
+        post :hide
+        post :unhide
+      end
+    end
   end
 
-  authenticate :user, lambda { |u| u.moderator? } do
-    get '/admin', to: redirect('/admin/reports', status: 302)
-  end
+  get '/admin', to: redirect('/admin/dashboard', status: 302)
 
   namespace :api do
     # PubSubHubbub outgoing subscriptions
@@ -247,16 +279,24 @@ Rails.application.routes.draw do
       resources :streaming, only: [:index]
       resources :custom_emojis, only: [:index]
       resources :suggestions, only: [:index, :destroy]
+      resources :scheduled_statuses, only: [:index, :show, :update, :destroy]
+
+      resources :conversations, only: [:index, :destroy] do
+        member do
+          post :read
+        end
+      end
 
       get '/search', to: 'search#index', as: :search
 
-      resources :follows,    only: [:create]
-      resources :media,      only: [:create, :update]
-      resources :blocks,     only: [:index]
-      resources :mutes,      only: [:index]
-      resources :favourites, only: [:index]
-      resources :reports,    only: [:index, :create]
-      resources :filters,    only: [:index, :create, :show, :update, :destroy]
+      resources :follows,      only: [:create]
+      resources :media,        only: [:create, :update]
+      resources :blocks,       only: [:index]
+      resources :mutes,        only: [:index]
+      resources :favourites,   only: [:index]
+      resources :reports,      only: [:create]
+      resources :filters,      only: [:index, :create, :show, :update, :destroy]
+      resources :endorsements, only: [:index]
 
       namespace :apps do
         get :verify_credentials, to: 'credentials#show'
@@ -281,6 +321,10 @@ Rails.application.routes.draw do
       resources :notifications, only: [:index, :show] do
         collection do
           post :clear
+          post :dismiss # Deprecated
+        end
+
+        member do
           post :dismiss
         end
       end
@@ -292,7 +336,7 @@ Rails.application.routes.draw do
         resources :relationships, only: :index
       end
 
-      resources :accounts, only: [:show] do
+      resources :accounts, only: [:create, :show] do
         resources :statuses, only: :index, controller: 'accounts/statuses'
         resources :followers, only: :index, controller: 'accounts/follower_accounts'
         resources :following, only: :index, controller: 'accounts/following_accounts'
@@ -306,6 +350,9 @@ Rails.application.routes.draw do
           post :mute
           post :unmute
         end
+
+        resource :pin, only: :create, controller: 'accounts/pins'
+        post :unpin, to: 'accounts/pins#destroy'
       end
 
       resources :lists, only: [:index, :create, :show, :update, :destroy] do
diff --git a/config/settings.yml b/config/settings.yml
index 190f6afcd1ab9cd7af78dd2d06a3696660dc17ed..4f7c2c8f32cc04348d89ec056a091b9b3eace7bf 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -1,19 +1,16 @@
-# config/app.yml for rails-settings-cached
-#
-# This file contains default values, and does not need to be edited
-# when configuring an instance.  These settings may be changed by an
-# Administrator using the Web UI.
-#
-# For more information, see docs/Running-Mastodon/Administration-guide.md
-#
+# This file contains default values, and does not need to be edited. All
+# important settings can be changed from the admin interface.
+
 defaults: &defaults
   site_title: Mastodon
+  site_short_description: ''
   site_description: ''
   site_extended_description: ''
   site_terms: ''
   site_contact_username: ''
   site_contact_email: ''
   open_registrations: true
+  profile_directory: true
   closed_registrations_message: ''
   open_deletion: true
   min_invite_role: 'admin'
@@ -25,12 +22,14 @@ defaults: &defaults
   boost_modal: false
   delete_modal: true
   auto_play_gif: false
-  display_sensitive_media: false
+  display_media: 'default'
+  expand_spoilers: false
   preview_sensitive_media: false
   reduce_motion: false
   system_font_ui: false
   noindex: false
   theme: 'default'
+  aggregate_reblogs: true
   notification_emails:
     follow: false
     reblog: false
@@ -38,6 +37,7 @@ defaults: &defaults
     mention: false
     follow_request: true
     digest: true
+    report: true
   interactions:
     must_be_follower: false
     must_be_following: false
@@ -49,11 +49,14 @@ defaults: &defaults
     - root
     - webmaster
     - administrator
+    - mod
+    - moderator
   disallowed_hashtags: # space separated string or list of hashtags without the hash
   bootstrap_timeline_accounts: ''
   activity_api_enabled: true
   peers_api_enabled: true
   show_known_fediverse_at_about_page: true
+
 development:
   <<: *defaults
 
diff --git a/config/sidekiq.yml b/config/sidekiq.yml
index 244e9ea48b422c5bf5d9b10cbb878ff541ebe679..0ec1742abfeb2547627c6691f972e553ff36dd58 100644
--- a/config/sidekiq.yml
+++ b/config/sidekiq.yml
@@ -1,11 +1,14 @@
 ---
 :concurrency: 5
 :queues:
-  - default
-  - push
-  - pull
-  - mailers
+  - [default, 6]
+  - [push, 4]
+  - [mailers, 2]
+  - [pull]
 :schedule:
+  scheduled_statuses_scheduler:
+    every: '5m'
+    class: Scheduler::ScheduledStatusesScheduler
   subscriptions_scheduler:
     cron: '<%= Random.rand(0..59) %> <%= Random.rand(4..6) %> * * *'
     class: Scheduler::SubscriptionsScheduler
@@ -33,3 +36,6 @@
   backup_cleanup_scheduler:
     cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *'
     class: Scheduler::BackupCleanupScheduler
+  pghero_scheduler:
+    cron: '0 0 * * *'
+    class: Scheduler::PgheroScheduler
diff --git a/config/webpack/configuration.js b/config/webpack/configuration.js
index cf8c0c7e1d33bd4a9a1c6c16107901b0958ca163..4d325a82877197bc37aa1e61606866f7c7766c48 100644
--- a/config/webpack/configuration.js
+++ b/config/webpack/configuration.js
@@ -7,7 +7,7 @@ const { readFileSync } = require('fs');
 
 const configPath = resolve('config', 'webpacker.yml');
 const loadersDir = join(__dirname, 'loaders');
-const settings = safeLoad(readFileSync(configPath), 'utf8')[env.NODE_ENV];
+const settings = safeLoad(readFileSync(configPath), 'utf8')[env.RAILS_ENV || env.NODE_ENV];
 
 const themePath = resolve('config', 'themes.yml');
 const themes = safeLoad(readFileSync(themePath), 'utf8');
diff --git a/config/webpack/development.js b/config/webpack/development.js
index 12670f5cd08ef634e8b816b5aa09a27296dad168..d54d919eca59ca5e79a48cc34e5a70c66b0b60d7 100644
--- a/config/webpack/development.js
+++ b/config/webpack/development.js
@@ -16,6 +16,8 @@ if (process.env.VAGRANT) {
 }
 
 module.exports = merge(sharedConfig, {
+  mode: 'development',
+
   devtool: 'cheap-module-eval-source-map',
 
   stats: {
diff --git a/config/webpack/loaders/babel.js b/config/webpack/loaders/babel.js
index e17d2fa7013ba5fc6812379ff253245654804185..7509617fdaa2a9e86d4b3bced21b7215f45dbffd 100644
--- a/config/webpack/loaders/babel.js
+++ b/config/webpack/loaders/babel.js
@@ -7,7 +7,6 @@ module.exports = {
   exclude: /node_modules/,
   loader: 'babel-loader',
   options: {
-    forceEnv: env,
     cacheDirectory: env === 'development' ? false : resolve(__dirname, '..', '..', '..', 'tmp', 'cache', 'babel-loader'),
   },
 };
diff --git a/config/webpack/loaders/sass.js b/config/webpack/loaders/sass.js
index 88d94c6846a80912abbb3af10946bad03015f082..67a1890b8f822117ff21d304f90494118a10ae4f 100644
--- a/config/webpack/loaders/sass.js
+++ b/config/webpack/loaders/sass.js
@@ -1,15 +1,23 @@
-const ExtractTextPlugin = require('extract-text-webpack-plugin');
-const { env } = require('../configuration.js');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 
 module.exports = {
-  test: /\.(scss|sass|css)$/i,
-  use: ExtractTextPlugin.extract({
-    fallback: 'style-loader',
-    use: [
-      { loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } },
-      { loader: 'postcss-loader', options: { sourceMap: true } },
-      'resolve-url-loader',
-      'sass-loader',
-    ],
-  }),
+  test: /\.s?css$/i,
+  use: [
+    MiniCssExtractPlugin.loader,
+    'css-loader',
+    {
+      loader: 'postcss-loader',
+      options: {
+        sourceMap: true,
+      },
+    },
+    {
+      loader: 'sass-loader',
+      options: {
+        fiber: require('fibers'),
+        implementation: require('sass'),
+        sourceMap: true,
+      },
+    },
+  ],
 };
diff --git a/config/webpack/production.js b/config/webpack/production.js
index 037a76a59206ee2d26706fcb5d842a2119483cbb..d37e11792b5b5fb2da800175b50ddd0b3a67e938 100644
--- a/config/webpack/production.js
+++ b/config/webpack/production.js
@@ -1,30 +1,21 @@
 // Note: You must restart bin/webpack-dev-server for changes to take effect
 
-const webpack = require('webpack');
 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('whatwg-url');
-
-let compressionAlgorithm;
-try {
-  const zopfli = require('node-zopfli');
-  compressionAlgorithm = (content, options, fn) => {
-    zopfli.gzip(content, options, fn);
-  };
-} catch (error) {
-  compressionAlgorithm = 'gzip';
-}
+const { URL } = require('url');
 
 let attachmentHost;
 
 if (process.env.S3_ENABLED === 'true') {
-  if (process.env.S3_CLOUDFRONT_HOST) {
-    attachmentHost = process.env.S3_CLOUDFRONT_HOST;
+  if (process.env.S3_ALIAS_HOST || process.env.S3_CLOUDFRONT_HOST) {
+    attachmentHost = process.env.S3_ALIAS_HOST || process.env.S3_CLOUDFRONT_HOST;
   } else {
     attachmentHost = process.env.S3_HOSTNAME || `s3-${process.env.S3_REGION || 'us-east-1'}.amazonaws.com`;
   }
@@ -36,6 +27,8 @@ if (process.env.S3_ENABLED === 'true') {
 }
 
 module.exports = merge(sharedConfig, {
+  mode: 'production',
+
   output: {
     filename: '[name]-[chunkhash].js',
     chunkFilename: '[name]-[chunkhash].js',
@@ -44,22 +37,32 @@ module.exports = merge(sharedConfig, {
   devtool: 'source-map', // separate sourcemap file, suitable for production
   stats: 'normal',
 
-  plugins: [
-    new webpack.optimize.UglifyJsPlugin({
-      sourceMap: true,
-      mangle: true,
+  optimization: {
+    minimize: true,
+    minimizer: [
+      new UglifyJsPlugin({
+        cache: true,
+        parallel: true,
+        sourceMap: true,
 
-      compress: {
-        warnings: false,
-      },
+        uglifyOptions: {
+          compress: {
+            warnings: false,
+          },
 
-      output: {
-        comments: false,
-      },
-    }),
+          output: {
+            comments: false,
+          },
+        },
+      }),
+    ],
+  },
+
+  plugins: [
     new CompressionPlugin({
-      asset: '[path].gz[query]',
-      algorithm: compressionAlgorithm,
+      algorithm(input, compressionOptions, callback) {
+        return zopfli.gzip(input, compressionOptions, callback);
+      },
       test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/,
     }),
     new BundleAnalyzerPlugin({ // generates report.html and stats.json
diff --git a/config/webpack/shared.js b/config/webpack/shared.js
index 50fa4817594cd2d7fe08cc724b8dd2838d699d38..d6199373b8458c9086e0a90dbbe261e145d76612 100644
--- a/config/webpack/shared.js
+++ b/config/webpack/shared.js
@@ -1,10 +1,10 @@
 // Note: You must restart bin/webpack-dev-server for changes to take effect
 
 const webpack = require('webpack');
-const { basename, dirname, join, relative, resolve, sep } = require('path');
+const { basename, dirname, join, relative, resolve } = require('path');
 const { sync } = require('glob');
-const ExtractTextPlugin = require('extract-text-webpack-plugin');
-const ManifestPlugin = require('webpack-manifest-plugin');
+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 localePackPaths = require('./generateLocalePacks');
@@ -39,6 +39,26 @@ module.exports = {
     publicPath: output.publicPath,
   },
 
+  optimization: {
+    runtimeChunk: {
+      name: 'common',
+    },
+    splitChunks: {
+      cacheGroups: {
+        default: false,
+        vendors: false,
+        common: {
+          name: 'common',
+          chunks: 'all',
+          minChunks: 2,
+          minSize: 0,
+          test: /^(?!.*[\\\/]node_modules[\\\/]react-intl[\\\/]).+$/,
+        },
+      },
+    },
+    occurrenceOrder: true,
+  },
+
   module: {
     rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)),
   },
@@ -52,25 +72,12 @@ module.exports = {
         resource.request = resource.request.replace(/^history/, 'history/es');
       }
     ),
-    new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css'),
-    new ManifestPlugin({
-      publicPath: output.publicPath,
-      writeToFileEmit: true,
+    new MiniCssExtractPlugin({
+      filename: env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css',
     }),
-    new webpack.optimize.CommonsChunkPlugin({
-      name: 'common',
-      minChunks: (module, count) => {
-        const reactIntlPathRegexp = new RegExp(`node_modules\\${sep}react-intl`);
-
-        if (module.resource && reactIntlPathRegexp.test(module.resource)) {
-          // skip react-intl because it's useless to put in the common chunk,
-          // e.g. because "shared" modules between zh-TW and zh-CN will never
-          // be loaded together
-          return false;
-        }
-
-        return count >= 2;
-      },
+    new AssetsManifestPlugin({
+      publicPath: true,
+      writeToDisk: true,
     }),
   ],
 
diff --git a/config/webpack/test.js b/config/webpack/test.js
index 6b2b073bb957e82c7bf01a88d46b459714b5ff6b..8b56eb92f29f37294e26df6f5ab1fda96d21d39f 100644
--- a/config/webpack/test.js
+++ b/config/webpack/test.js
@@ -3,4 +3,6 @@
 const merge = require('webpack-merge');
 const sharedConfig = require('./shared.js');
 
-module.exports = merge(sharedConfig, {});
+module.exports = merge(sharedConfig, {
+  mode: 'development',
+});
diff --git a/config/webpacker.yml b/config/webpacker.yml
index 8d8470651ac41cc583317e49cecd0b0502b763f0..ea814a0e65f6156c250551d3174205b2a5243689 100644
--- a/config/webpacker.yml
+++ b/config/webpacker.yml
@@ -40,6 +40,10 @@ test:
   # 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
+
 production:
   <<: *default
 
diff --git a/db/migrate/20160306172223_create_doorkeeper_tables.rb b/db/migrate/20160306172223_create_doorkeeper_tables.rb
index 9e173a43f32ea53675cc6711caa58d1259c5d17c..462343e888c917bbfa541a017485ae6c8b4182e1 100644
--- a/db/migrate/20160306172223_create_doorkeeper_tables.rb
+++ b/db/migrate/20160306172223_create_doorkeeper_tables.rb
@@ -34,12 +34,12 @@ class CreateDoorkeeperTables < ActiveRecord::Migration[4.2]
       # https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator
       #
       # t.text     :token,             null: false
-      t.string   :token,             null: false
+      t.string   :token, null: false
 
       t.string   :refresh_token
       t.integer  :expires_in
       t.datetime :revoked_at
-      t.datetime :created_at,        null: false
+      t.datetime :created_at, null: false
       t.string   :scopes
     end
 
diff --git a/db/migrate/20160314164231_add_owner_to_application.rb b/db/migrate/20160314164231_add_owner_to_application.rb
index 1919f09a170d9364fab77dbda30b37fe0399cab3..553c18b5ebeff9022bad4d1d798dd1982f925317 100644
--- a/db/migrate/20160314164231_add_owner_to_application.rb
+++ b/db/migrate/20160314164231_add_owner_to_application.rb
@@ -4,4 +4,4 @@ class AddOwnerToApplication < ActiveRecord::Migration[4.2]
     add_column :oauth_applications, :owner_type, :string, null: true
     add_index :oauth_applications, [:owner_id, :owner_type]
   end
-end
\ No newline at end of file
+end
diff --git a/db/migrate/20161006213403_rails_settings_migration.rb b/db/migrate/20161006213403_rails_settings_migration.rb
index 3b2e637fc7c3b6d7d8f996cf18c527266f6abe80..42875d7cbda3e0a78ac22036e4d6cf45a1649c10 100644
--- a/db/migrate/20161006213403_rails_settings_migration.rb
+++ b/db/migrate/20161006213403_rails_settings_migration.rb
@@ -7,7 +7,7 @@ end
 class RailsSettingsMigration < MIGRATION_BASE_CLASS
   def self.up
     create_table :settings do |t|
-      t.string     :var,    :null => false
+      t.string     :var, :null => false
       t.text       :value
       t.references :target, :null => false, :polymorphic => true
       t.timestamps :null => true
diff --git a/db/migrate/20170105224407_add_shortcode_to_media_attachments.rb b/db/migrate/20170105224407_add_shortcode_to_media_attachments.rb
index 2685ae150ec62b6ecf09c376829ddb400c14ec61..fba46a4b63b3510e788265d3a277a4026027caad 100644
--- a/db/migrate/20170105224407_add_shortcode_to_media_attachments.rb
+++ b/db/migrate/20170105224407_add_shortcode_to_media_attachments.rb
@@ -8,7 +8,7 @@ class AddShortcodeToMediaAttachments < ActiveRecord::Migration[5.0]
   end
 
   def down
-  	remove_index :media_attachments, :shortcode
-  	remove_column :media_attachments, :shortcode
+    remove_index :media_attachments, :shortcode
+    remove_column :media_attachments, :shortcode
   end
 end
diff --git a/db/migrate/20170606113804_change_tag_search_index_to_btree.rb b/db/migrate/20170606113804_change_tag_search_index_to_btree.rb
index 5248e17202606a5c75d94d06da497cc18bd97189..979df2e74422857bac60ee50e8c114cfe93de708 100644
--- a/db/migrate/20170606113804_change_tag_search_index_to_btree.rb
+++ b/db/migrate/20170606113804_change_tag_search_index_to_btree.rb
@@ -1,5 +1,4 @@
 class ChangeTagSearchIndexToBtree < ActiveRecord::Migration[5.1]
-
   def up
     remove_index :tags, name: :hashtag_search_index
     execute 'CREATE INDEX hashtag_search_index ON tags (name text_pattern_ops);'
diff --git a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb
index 0410938c9b8cadc95b23d0c82d129c794cb567f4..a498396b75e209b63cef8ff4f1174b0aa691ca39 100644
--- a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb
+++ b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb
@@ -8,7 +8,7 @@ class AddHideNotificationsToMute < ActiveRecord::Migration[5.1]
   def up
     add_column_with_default :mutes, :hide_notifications, :boolean, default: true, allow_null: false
   end
-  
+
   def down
     remove_column :mutes, :hide_notifications
   end
diff --git a/db/migrate/20170920032311_fix_reblogs_in_feeds.rb b/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
index 439c5fca08bb8bac35e88a416f639834cef51d96..5654bf6f8773070de06863bf2dc68700f8dcdc2c 100644
--- a/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
+++ b/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
@@ -28,7 +28,7 @@ class FixReblogsInFeeds < ActiveRecord::Migration[5.1]
 
       -- So, first, we iterate over the user's feed to find any reblogs.
       local items = redis.call('zrange', timeline_key, 0, -1, 'withscores')
-      
+
       for i = 1, #items, 2 do
         local reblogged_id = items[i]
         local reblogging_id = items[i + 1]
diff --git a/db/migrate/20171028221157_add_reblogs_to_follows.rb b/db/migrate/20171028221157_add_reblogs_to_follows.rb
index 4b5d5b7ff362971ed00b88eb2edf7d1a9c5c8f7b..3b2e46ed8a6d15941a9de1b0feff9c285f889dad 100644
--- a/db/migrate/20171028221157_add_reblogs_to_follows.rb
+++ b/db/migrate/20171028221157_add_reblogs_to_follows.rb
@@ -11,7 +11,7 @@ class AddReblogsToFollows < ActiveRecord::Migration[5.1]
       add_column_with_default :follow_requests, :show_reblogs, :boolean, default: true, allow_null: false
     end
   end
-  
+
   def down
     remove_column :follows, :show_reblogs
     remove_column :follow_requests, :show_reblogs
diff --git a/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb b/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb
index 120f744026418bceb4b982ac6d9165bb41dfaa96..3369e3b9e97ab7f28fbf69584c908807e5437756 100644
--- a/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb
+++ b/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb
@@ -1,5 +1,3 @@
-require Rails.root.join('lib', 'mastodon', 'migration_helpers')
-
 class ChangeAccountIdNonnullableInLists < ActiveRecord::Migration[5.1]
   def change
     change_column_null :lists, :account_id, false
diff --git a/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
index 4a8761fec3d2126e2a431cf47250fd564663b3fc..ccd2ec7eac575646d673e0cbc8f35a0212f4d4c9 100644
--- a/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
+++ b/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
@@ -5,7 +5,7 @@ class RevertIndexChangeOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecor
 
   def change
     safety_assured do
-      add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_exists?(:statuses, name: "index_statuses_20180106")
+      add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_name_exists?(:statuses, "index_statuses_20180106")
     end
 
     # These index may not exists (see migration 20180514130000)
diff --git a/db/migrate/20180528141303_fix_accounts_unique_index.rb b/db/migrate/20180528141303_fix_accounts_unique_index.rb
index 96cee37f9cba16c0b24f8777aca210888641836f..bd4e158b7ecccc39892957ceab8b869b452d41b0 100644
--- a/db/migrate/20180528141303_fix_accounts_unique_index.rb
+++ b/db/migrate/20180528141303_fix_accounts_unique_index.rb
@@ -1,4 +1,17 @@
 class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2]
+  class Account < ApplicationRecord
+    # Dummy class, to make migration possible across version changes
+    has_one :user, inverse_of: :account
+
+    def local?
+      domain.nil?
+    end
+
+    def acct
+      local? ? username : "#{username}@#{domain}"
+    end
+  end
+
   disable_ddl_transaction!
 
   def up
diff --git a/db/migrate/20180711152640_create_relays.rb b/db/migrate/20180711152640_create_relays.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8762f473a29e11e8e96afce553ff78650f5dd4b2
--- /dev/null
+++ b/db/migrate/20180711152640_create_relays.rb
@@ -0,0 +1,12 @@
+class CreateRelays < ActiveRecord::Migration[5.2]
+  def change
+    create_table :relays do |t|
+      t.string :inbox_url, default: '', null: false
+      t.boolean :enabled, default: false, null: false, index: true
+
+      t.string :follow_activity_id
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20180808175627_create_account_pins.rb b/db/migrate/20180808175627_create_account_pins.rb
new file mode 100644
index 0000000000000000000000000000000000000000..43d8185be9d459caf21498a7bac95eeb50083011
--- /dev/null
+++ b/db/migrate/20180808175627_create_account_pins.rb
@@ -0,0 +1,12 @@
+class CreateAccountPins < ActiveRecord::Migration[5.2]
+  def change
+    create_table :account_pins do |t|
+      t.belongs_to :account, foreign_key: { on_delete: :cascade }
+      t.belongs_to :target_account, foreign_key: { on_delete: :cascade, to_table: :accounts }
+
+      t.timestamps
+    end
+
+    add_index :account_pins, [:account_id, :target_account_id], unique: true
+  end
+end
diff --git a/db/migrate/20180812123222_change_relays_enabled.rb b/db/migrate/20180812123222_change_relays_enabled.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c4fd8179be628eabd07d16c5de8caedf76f59f56
--- /dev/null
+++ b/db/migrate/20180812123222_change_relays_enabled.rb
@@ -0,0 +1,19 @@
+class ChangeRelaysEnabled < ActiveRecord::Migration[5.2]
+  def up
+    # The relays table is supposed to be very small,
+    # single-digit number of rows, so this should be fine
+    safety_assured do
+      add_column :relays, :state, :integer, default: 0, null: false
+
+      # At the time of this migration, no relays reject anyone, so if
+      # there are enabled ones, they are accepted
+      execute 'UPDATE relays SET state = 2 WHERE enabled = true'
+      remove_column :relays, :enabled
+    end
+  end
+
+  def down
+    remove_column :relays, :state
+    add_column :relays, :enabled, :boolean, default: false, null: false
+  end
+end
diff --git a/db/migrate/20180812162710_create_status_stats.rb b/db/migrate/20180812162710_create_status_stats.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d4da36fe7860c12cfd75e87489ba06acee3b79ef
--- /dev/null
+++ b/db/migrate/20180812162710_create_status_stats.rb
@@ -0,0 +1,12 @@
+class CreateStatusStats < ActiveRecord::Migration[5.2]
+  def change
+    create_table :status_stats do |t|
+      t.belongs_to :status, null: false, foreign_key: { on_delete: :cascade }, index: { unique: true }
+      t.bigint :replies_count, null: false, default: 0
+      t.bigint :reblogs_count, null: false, default: 0
+      t.bigint :favourites_count, null: false, default: 0
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20180812173710_copy_status_stats.rb b/db/migrate/20180812173710_copy_status_stats.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ff10c18d9d6b847cead9510b77ea4090fd903ef8
--- /dev/null
+++ b/db/migrate/20180812173710_copy_status_stats.rb
@@ -0,0 +1,54 @@
+class CopyStatusStats < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      if supports_upsert?
+        up_fast
+      else
+        up_slow
+      end
+    end
+  end
+
+  def down
+    # Nothing
+  end
+
+  private
+
+  def supports_upsert?
+    version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i
+    version >= 90500
+  end
+
+  def up_fast
+    say 'Upsert is available, importing counters using the fast method'
+
+    Status.unscoped.select('id').find_in_batches(batch_size: 5_000) do |statuses|
+      execute <<-SQL.squish
+        INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at)
+        SELECT id, reblogs_count, favourites_count, created_at, updated_at
+        FROM statuses
+        WHERE id IN (#{statuses.map(&:id).join(', ')})
+        ON CONFLICT (status_id) DO UPDATE
+        SET reblogs_count = EXCLUDED.reblogs_count, favourites_count = EXCLUDED.favourites_count
+      SQL
+    end
+  end
+
+  def up_slow
+    say 'Upsert is not available in PostgreSQL below 9.5, falling back to slow import of counters'
+
+    # We cannot use bulk INSERT or overarching transactions here because of possible
+    # uniqueness violations that we need to skip over
+    Status.unscoped.select('id, reblogs_count, favourites_count, created_at, updated_at').find_each do |status|
+      begin
+        params = [[nil, status.id], [nil, status.reblogs_count], [nil, status.favourites_count], [nil, status.created_at], [nil, status.updated_at]]
+        exec_insert('INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)', nil, params)
+      rescue ActiveRecord::RecordNotUnique
+        next
+      end
+    end
+  end
+end
diff --git a/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb b/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7077a4e659778ae95c66aa867a313eaafe08149b
--- /dev/null
+++ b/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb
@@ -0,0 +1,23 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddConfidentialToDoorkeeperApplication < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      add_column_with_default(
+        :oauth_applications,
+        :confidential,
+        :boolean,
+        allow_null: false,
+        default: true # maintaining backwards compatibility: require secrets
+      )
+    end
+  end
+
+  def down
+    remove_column :oauth_applications, :confidential
+  end
+end
diff --git a/db/migrate/20180820232245_add_foreign_key_indices.rb b/db/migrate/20180820232245_add_foreign_key_indices.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e346c1f5bddd163098d3851765b68fac5a619867
--- /dev/null
+++ b/db/migrate/20180820232245_add_foreign_key_indices.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddForeignKeyIndices < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def change
+    add_index :follows, :target_account_id, algorithm: :concurrently
+    add_index :blocks, :target_account_id, algorithm: :concurrently
+    add_index :mutes, :target_account_id, algorithm: :concurrently
+    add_index :notifications, :from_account_id, algorithm: :concurrently
+    add_index :accounts, :moved_to_account_id, algorithm: :concurrently
+    add_index :statuses, :in_reply_to_account_id, algorithm: :concurrently
+    add_index :session_activations, :access_token_id, algorithm: :concurrently
+    add_index :oauth_access_grants, :resource_owner_id, algorithm: :concurrently
+  end
+end
diff --git a/db/migrate/20180929222014_create_account_conversations.rb b/db/migrate/20180929222014_create_account_conversations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..53fa137e1547b4cb7f8df6b8f9bab81e5fe55618
--- /dev/null
+++ b/db/migrate/20180929222014_create_account_conversations.rb
@@ -0,0 +1,14 @@
+class CreateAccountConversations < ActiveRecord::Migration[5.2]
+  def change
+    create_table :account_conversations do |t|
+      t.belongs_to :account, foreign_key: { on_delete: :cascade }
+      t.belongs_to :conversation, foreign_key: { on_delete: :cascade }
+      t.bigint :participant_account_ids, array: true, null: false, default: []
+      t.bigint :status_ids, array: true, null: false, default: []
+      t.bigint :last_status_id, null: true, default: nil
+      t.integer :lock_version, null: false, default: 0
+    end
+
+    add_index :account_conversations, [:account_id, :conversation_id, :participant_account_ids], unique: true, name: 'index_unique_conversations'
+  end
+end
diff --git a/db/migrate/20181007025445_create_pghero_space_stats.rb b/db/migrate/20181007025445_create_pghero_space_stats.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6198a6f84680e7705cefe9317426a4e00e006771
--- /dev/null
+++ b/db/migrate/20181007025445_create_pghero_space_stats.rb
@@ -0,0 +1,13 @@
+class CreatePgheroSpaceStats < ActiveRecord::Migration[5.2]
+  def change
+    create_table :pghero_space_stats do |t|
+      t.text :database
+      t.text :schema
+      t.text :relation
+      t.integer :size, limit: 8
+      t.timestamp :captured_at
+    end
+
+    add_index :pghero_space_stats, [:database, :captured_at]
+  end
+end
diff --git a/db/migrate/20181010141500_add_silent_to_mentions.rb b/db/migrate/20181010141500_add_silent_to_mentions.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dbb4fba263714d398df7804c94a4ae112266c744
--- /dev/null
+++ b/db/migrate/20181010141500_add_silent_to_mentions.rb
@@ -0,0 +1,23 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddSilentToMentions < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      add_column_with_default(
+        :mentions,
+        :silent,
+        :boolean,
+        allow_null: false,
+        default: false
+      )
+    end
+  end
+
+  def down
+    remove_column :mentions, :silent
+  end
+end
diff --git a/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb b/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f05d50fcd9371ea9b85853f82f6dcba4cd69bf8a
--- /dev/null
+++ b/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb
@@ -0,0 +1,17 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddRejectReportsToDomainBlocks < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      add_column_with_default :domain_blocks, :reject_reports, :boolean, default: false, allow_null: false
+    end
+  end
+
+  def down
+    remove_column :domain_blocks, :reject_reports
+  end
+end
diff --git a/db/migrate/20181018205649_add_unread_to_account_conversations.rb b/db/migrate/20181018205649_add_unread_to_account_conversations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3c28b9a64169320d2a18c5d62202b0f8febe1a31
--- /dev/null
+++ b/db/migrate/20181018205649_add_unread_to_account_conversations.rb
@@ -0,0 +1,23 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddUnreadToAccountConversations < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      add_column_with_default(
+        :account_conversations,
+        :unread,
+        :boolean,
+        allow_null: false,
+        default: false
+      )
+    end
+  end
+
+  def down
+    remove_column :account_conversations, :unread, :boolean
+  end
+end
diff --git a/db/migrate/20181024224956_migrate_account_conversations.rb b/db/migrate/20181024224956_migrate_account_conversations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b718f9e1d524e73782bc5824372307c8cc24944b
--- /dev/null
+++ b/db/migrate/20181024224956_migrate_account_conversations.rb
@@ -0,0 +1,57 @@
+class MigrateAccountConversations < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def up
+    say ''
+    say 'WARNING: This migration may take a *long* time for large instances'
+    say 'It will *not* lock tables for any significant time, but it may run'
+    say 'for a very long time. We will pause for 10 seconds to allow you to'
+    say 'interrupt this migration if you are not ready.'
+    say ''
+
+    10.downto(1) do |i|
+      say "Continuing in #{i} second#{i == 1 ? '' : 's'}...", true
+      sleep 1
+    end
+
+    migrated  = 0
+    last_time = Time.zone.now
+
+    local_direct_statuses.includes(:account, mentions: :account).find_each do |status|
+      AccountConversation.add_status(status.account, status)
+      migrated += 1
+
+      if Time.zone.now - last_time > 1
+        say_progress(migrated)
+        last_time = Time.zone.now
+      end
+    end
+
+    notifications_about_direct_statuses.includes(:account, mention: { status: [:account, mentions: :account] }).find_each do |notification|
+      AccountConversation.add_status(notification.account, notification.target_status)
+      migrated += 1
+
+      if Time.zone.now - last_time > 1
+        say_progress(migrated)
+        last_time = Time.zone.now
+      end
+    end
+  end
+
+  def down
+  end
+
+  private
+
+  def say_progress(migrated)
+    say "Migrated #{migrated} rows", true
+  end
+
+  def local_direct_statuses
+    Status.unscoped.local.where(visibility: :direct)
+  end
+
+  def notifications_about_direct_statuses
+    Notification.joins(mention: :status).where(activity_type: 'Mention', statuses: { visibility: :direct })
+  end
+end
diff --git a/db/migrate/20181026034033_remove_faux_remote_account_duplicates.rb b/db/migrate/20181026034033_remove_faux_remote_account_duplicates.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bd4f4c2a36852fb03fc9c002594f6436bfd60043
--- /dev/null
+++ b/db/migrate/20181026034033_remove_faux_remote_account_duplicates.rb
@@ -0,0 +1,16 @@
+class RemoveFauxRemoteAccountDuplicates < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def up
+    local_domain = Rails.configuration.x.local_domain
+
+    # Just a safety measure to ensure that under no circumstance
+    # we will query `domain IS NULL` because that would return
+    # actually local accounts, the originals
+    return if local_domain.nil?
+
+    Account.where(domain: local_domain).in_batches.destroy_all
+  end
+
+  def down; end
+end
diff --git a/db/migrate/20181116165755_create_account_stats.rb b/db/migrate/20181116165755_create_account_stats.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a798e8166e981e3555e2e6d132a3c40cae6d01ab
--- /dev/null
+++ b/db/migrate/20181116165755_create_account_stats.rb
@@ -0,0 +1,12 @@
+class CreateAccountStats < ActiveRecord::Migration[5.2]
+  def change
+    create_table :account_stats do |t|
+      t.belongs_to :account, null: false, foreign_key: { on_delete: :cascade }, index: { unique: true }
+      t.bigint :statuses_count, null: false, default: 0
+      t.bigint :following_count, null: false, default: 0
+      t.bigint :followers_count, null: false, default: 0
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20181116173541_copy_account_stats.rb b/db/migrate/20181116173541_copy_account_stats.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bb523fbbd31c3fadab0d3d5241100d0437391d02
--- /dev/null
+++ b/db/migrate/20181116173541_copy_account_stats.rb
@@ -0,0 +1,54 @@
+class CopyAccountStats < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      if supports_upsert?
+        up_fast
+      else
+        up_slow
+      end
+    end
+  end
+
+  def down
+    # Nothing
+  end
+
+  private
+
+  def supports_upsert?
+    version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i
+    version >= 90500
+  end
+
+  def up_fast
+    say 'Upsert is available, importing counters using the fast method'
+
+    Account.unscoped.select('id').find_in_batches(batch_size: 5_000) do |accounts|
+      execute <<-SQL.squish
+        INSERT INTO account_stats (account_id, statuses_count, following_count, followers_count, created_at, updated_at)
+        SELECT id, statuses_count, following_count, followers_count, created_at, updated_at
+        FROM accounts
+        WHERE id IN (#{accounts.map(&:id).join(', ')})
+        ON CONFLICT (account_id) DO UPDATE
+        SET statuses_count = EXCLUDED.statuses_count, following_count = EXCLUDED.following_count, followers_count = EXCLUDED.followers_count
+      SQL
+    end
+  end
+
+  def up_slow
+    say 'Upsert is not available in PostgreSQL below 9.5, falling back to slow import of counters'
+
+    # We cannot use bulk INSERT or overarching transactions here because of possible
+    # 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]]
+        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
+      end
+    end
+  end
+end
diff --git a/db/migrate/20181127130500_identity_id_to_bigint.rb b/db/migrate/20181127130500_identity_id_to_bigint.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5f388aca7c7e6eb7b0a3279e28f70d0f4dc06f17
--- /dev/null
+++ b/db/migrate/20181127130500_identity_id_to_bigint.rb
@@ -0,0 +1,27 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class IdentityIdToBigint < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      change_column_type_concurrently :identities, :id, :bigint
+      cleanup_concurrent_column_type_change :identities, :id
+
+      change_column_type_concurrently :identities, :user_id, :bigint
+      cleanup_concurrent_column_type_change :identities, :user_id
+    end
+  end
+
+  def down
+    safety_assured do
+      change_column_type_concurrently :identities, :id, :integer
+      cleanup_concurrent_column_type_change :identities, :id
+
+      change_column_type_concurrently :identities, :user_id, :integer
+      cleanup_concurrent_column_type_change :identities, :user_id
+    end
+  end
+end
diff --git a/db/migrate/20181203003808_create_accounts_tags_join_table.rb b/db/migrate/20181203003808_create_accounts_tags_join_table.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3c275c2b785c2faa4a4eb2f521b81acd332cea17
--- /dev/null
+++ b/db/migrate/20181203003808_create_accounts_tags_join_table.rb
@@ -0,0 +1,8 @@
+class CreateAccountsTagsJoinTable < ActiveRecord::Migration[5.2]
+  def change
+    create_join_table :accounts, :tags do |t|
+      t.index [:account_id, :tag_id]
+      t.index [:tag_id, :account_id], unique: true
+    end
+  end
+end
diff --git a/db/migrate/20181203021853_add_discoverable_to_accounts.rb b/db/migrate/20181203021853_add_discoverable_to_accounts.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5bbae2203e0861b0a18ba59c65959e7e7de8119c
--- /dev/null
+++ b/db/migrate/20181203021853_add_discoverable_to_accounts.rb
@@ -0,0 +1,5 @@
+class AddDiscoverableToAccounts < ActiveRecord::Migration[5.2]
+  def change
+    add_column :accounts, :discoverable, :boolean
+  end
+end
diff --git a/db/migrate/20181204193439_add_last_status_at_to_account_stats.rb b/db/migrate/20181204193439_add_last_status_at_to_account_stats.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9466627071503682aba591344992e1663420870e
--- /dev/null
+++ b/db/migrate/20181204193439_add_last_status_at_to_account_stats.rb
@@ -0,0 +1,5 @@
+class AddLastStatusAtToAccountStats < ActiveRecord::Migration[5.2]
+  def change
+    add_column :account_stats, :last_status_at, :datetime
+  end
+end
diff --git a/db/migrate/20181204215309_create_account_tag_stats.rb b/db/migrate/20181204215309_create_account_tag_stats.rb
new file mode 100644
index 0000000000000000000000000000000000000000..15ed8587e39d2ab72a205c768d1e82a0935d5a76
--- /dev/null
+++ b/db/migrate/20181204215309_create_account_tag_stats.rb
@@ -0,0 +1,11 @@
+class CreateAccountTagStats < ActiveRecord::Migration[5.2]
+  def change
+    create_table :account_tag_stats do |t|
+      t.belongs_to :tag, null: false, foreign_key: { on_delete: :cascade }, index: { unique: true }
+      t.bigint :accounts_count, default: 0, null: false
+      t.boolean :hidden, default: false, null: false
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20181207011115_downcase_custom_emoji_domains.rb b/db/migrate/20181207011115_downcase_custom_emoji_domains.rb
new file mode 100644
index 0000000000000000000000000000000000000000..65f1fc8d938c835fd8b6742ac1918914f6059dbd
--- /dev/null
+++ b/db/migrate/20181207011115_downcase_custom_emoji_domains.rb
@@ -0,0 +1,15 @@
+class DowncaseCustomEmojiDomains < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def up
+    duplicates = CustomEmoji.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM custom_emojis GROUP BY shortcode, lower(domain) HAVING count(*) > 1').to_hash
+
+    duplicates.each do |row|
+      CustomEmoji.where(id: row['ids'].split(',')[0...-1]).destroy_all
+    end
+
+    CustomEmoji.in_batches.update_all('domain = lower(domain)')
+  end
+
+  def down; end
+end
diff --git a/db/migrate/20181213184704_create_account_warnings.rb b/db/migrate/20181213184704_create_account_warnings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e768be27784c667720d8c503babf31da4965f68d
--- /dev/null
+++ b/db/migrate/20181213184704_create_account_warnings.rb
@@ -0,0 +1,12 @@
+class CreateAccountWarnings < ActiveRecord::Migration[5.2]
+  def change
+    create_table :account_warnings do |t|
+      t.belongs_to :account, foreign_key: { on_delete: :nullify }
+      t.belongs_to :target_account, foreign_key: { to_table: 'accounts', on_delete: :cascade }
+      t.integer :action, null: false, default: 0
+      t.text :text, null: false, default: ''
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20181213185533_create_account_warning_presets.rb b/db/migrate/20181213185533_create_account_warning_presets.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9c81f1b5e6a522aa143a37fe7ab60c4bb747167c
--- /dev/null
+++ b/db/migrate/20181213185533_create_account_warning_presets.rb
@@ -0,0 +1,9 @@
+class CreateAccountWarningPresets < ActiveRecord::Migration[5.2]
+  def change
+    create_table :account_warning_presets do |t|
+      t.text :text, null: false, default: ''
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20181219235220_add_created_by_application_id_to_users.rb b/db/migrate/20181219235220_add_created_by_application_id_to_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..17ce900af30ea8b4fb4c138c0b402f4600619068
--- /dev/null
+++ b/db/migrate/20181219235220_add_created_by_application_id_to_users.rb
@@ -0,0 +1,8 @@
+class AddCreatedByApplicationIdToUsers < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def change
+    add_reference :users, :created_by_application, foreign_key: { to_table: 'oauth_applications', on_delete: :nullify }, index: false
+    add_index :users, :created_by_application_id, algorithm: :concurrently
+  end
+end
diff --git a/db/migrate/20181226021420_add_also_known_as_to_accounts.rb b/db/migrate/20181226021420_add_also_known_as_to_accounts.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1fd9566803ae8ff9f5997ff1b9e0f90f724cc720
--- /dev/null
+++ b/db/migrate/20181226021420_add_also_known_as_to_accounts.rb
@@ -0,0 +1,5 @@
+class AddAlsoKnownAsToAccounts < ActiveRecord::Migration[5.2]
+  def change
+    add_column :accounts, :also_known_as, :string, array: true
+  end
+end
diff --git a/db/migrate/20190103124649_create_scheduled_statuses.rb b/db/migrate/20190103124649_create_scheduled_statuses.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2b78073b85e2dee942dadef72c0ac85750372707
--- /dev/null
+++ b/db/migrate/20190103124649_create_scheduled_statuses.rb
@@ -0,0 +1,9 @@
+class CreateScheduledStatuses < ActiveRecord::Migration[5.2]
+  def change
+    create_table :scheduled_statuses do |t|
+      t.belongs_to :account, foreign_key: { on_delete: :cascade }
+      t.datetime :scheduled_at, index: true
+      t.jsonb :params
+    end
+  end
+end
diff --git a/db/migrate/20190103124754_add_scheduled_status_id_to_media_attachments.rb b/db/migrate/20190103124754_add_scheduled_status_id_to_media_attachments.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6f6cf23513465c33472498dbe23bc3810090d1bd
--- /dev/null
+++ b/db/migrate/20190103124754_add_scheduled_status_id_to_media_attachments.rb
@@ -0,0 +1,8 @@
+class AddScheduledStatusIdToMediaAttachments < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def change
+    add_reference :media_attachments, :scheduled_status, foreign_key: { on_delete: :nullify }, index: false
+    add_index :media_attachments, :scheduled_status_id, algorithm: :concurrently
+  end
+end
diff --git a/db/migrate/20190117114553_create_tombstones.rb b/db/migrate/20190117114553_create_tombstones.rb
new file mode 100644
index 0000000000000000000000000000000000000000..06d6d8c5ad01aafe577c2ae160a9a81dc0c157c5
--- /dev/null
+++ b/db/migrate/20190117114553_create_tombstones.rb
@@ -0,0 +1,12 @@
+class CreateTombstones < ActiveRecord::Migration[5.2]
+  def change
+    create_table :tombstones do |t|
+      t.belongs_to :account, foreign_key: { on_delete: :cascade }
+      t.string :uri, null: false
+
+      t.timestamps
+    end
+
+    add_index :tombstones, :uri
+  end
+end
diff --git a/app/javascript/mastodon/.gitkeep b/db/post_migrate/.gitkeep
similarity index 100%
rename from app/javascript/mastodon/.gitkeep
rename to db/post_migrate/.gitkeep
diff --git a/db/post_migrate/20180813113448_copy_status_stats_cleanup.rb b/db/post_migrate/20180813113448_copy_status_stats_cleanup.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f3ae772c79e737e82a56f7304680a27abc131e14
--- /dev/null
+++ b/db/post_migrate/20180813113448_copy_status_stats_cleanup.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class CopyStatusStatsCleanup < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def change
+    safety_assured do
+      remove_column :statuses, :reblogs_count, :integer, default: 0, null: false
+      remove_column :statuses, :favourites_count, :integer, default: 0, null: false
+    end
+  end
+end
diff --git a/db/post_migrate/20181116184611_copy_account_stats_cleanup.rb b/db/post_migrate/20181116184611_copy_account_stats_cleanup.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9267e9b2c6e3d4faef6c3d0e69fe5cd9b6c29e8a
--- /dev/null
+++ b/db/post_migrate/20181116184611_copy_account_stats_cleanup.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class CopyAccountStatsCleanup < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def change
+    safety_assured do
+      remove_column :accounts, :statuses_count, :integer, default: 0, null: false
+      remove_column :accounts, :following_count, :integer, default: 0, null: false
+      remove_column :accounts, :followers_count, :integer, default: 0, null: false
+    end
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 02032c54826b47ae1dc0bf13bdfff0a133c7dcef..3487adf08852c02983c7408dbff3d84356aae99d 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,11 +10,24 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2018_07_07_154237) do
+ActiveRecord::Schema.define(version: 2019_01_17_114553) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
 
+  create_table "account_conversations", force: :cascade do |t|
+    t.bigint "account_id"
+    t.bigint "conversation_id"
+    t.bigint "participant_account_ids", default: [], null: false, array: true
+    t.bigint "status_ids", default: [], null: false, array: true
+    t.bigint "last_status_id"
+    t.integer "lock_version", default: 0, null: false
+    t.boolean "unread", default: false, null: false
+    t.index ["account_id", "conversation_id", "participant_account_ids"], name: "index_unique_conversations", unique: true
+    t.index ["account_id"], name: "index_account_conversations_on_account_id"
+    t.index ["conversation_id"], name: "index_account_conversations_on_conversation_id"
+  end
+
   create_table "account_domain_blocks", force: :cascade do |t|
     t.string "domain"
     t.datetime "created_at", null: false
@@ -33,6 +46,53 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.index ["target_account_id"], name: "index_account_moderation_notes_on_target_account_id"
   end
 
+  create_table "account_pins", force: :cascade do |t|
+    t.bigint "account_id"
+    t.bigint "target_account_id"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["account_id", "target_account_id"], name: "index_account_pins_on_account_id_and_target_account_id", unique: true
+    t.index ["account_id"], name: "index_account_pins_on_account_id"
+    t.index ["target_account_id"], name: "index_account_pins_on_target_account_id"
+  end
+
+  create_table "account_stats", force: :cascade do |t|
+    t.bigint "account_id", null: false
+    t.bigint "statuses_count", default: 0, null: false
+    t.bigint "following_count", default: 0, null: false
+    t.bigint "followers_count", default: 0, null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.datetime "last_status_at"
+    t.index ["account_id"], name: "index_account_stats_on_account_id", unique: true
+  end
+
+  create_table "account_tag_stats", force: :cascade do |t|
+    t.bigint "tag_id", null: false
+    t.bigint "accounts_count", default: 0, null: false
+    t.boolean "hidden", default: false, null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["tag_id"], name: "index_account_tag_stats_on_tag_id", unique: true
+  end
+
+  create_table "account_warning_presets", force: :cascade do |t|
+    t.text "text", default: "", null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+  end
+
+  create_table "account_warnings", force: :cascade do |t|
+    t.bigint "account_id"
+    t.bigint "target_account_id"
+    t.integer "action", default: 0, null: false
+    t.text "text", default: "", null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["account_id"], name: "index_account_warnings_on_account_id"
+    t.index ["target_account_id"], name: "index_account_warnings_on_target_account_id"
+  end
+
   create_table "accounts", force: :cascade do |t|
     t.string "username", default: "", null: false
     t.string "domain"
@@ -62,9 +122,6 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.boolean "suspended", default: false, null: false
     t.boolean "locked", default: false, null: false
     t.string "header_remote_url", default: "", null: false
-    t.integer "statuses_count", default: 0, null: false
-    t.integer "followers_count", default: 0, null: false
-    t.integer "following_count", default: 0, null: false
     t.datetime "last_webfingered_at"
     t.string "inbox_url", default: "", null: false
     t.string "outbox_url", default: "", null: false
@@ -76,12 +133,22 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.string "featured_collection_url"
     t.jsonb "fields"
     t.string "actor_type"
+    t.boolean "discoverable"
+    t.string "also_known_as", array: true
     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"
     t.index ["uri"], name: "index_accounts_on_uri"
     t.index ["url"], name: "index_accounts_on_url"
   end
 
+  create_table "accounts_tags", id: false, force: :cascade do |t|
+    t.bigint "account_id", null: false
+    t.bigint "tag_id", null: false
+    t.index ["account_id", "tag_id"], name: "index_accounts_tags_on_account_id_and_tag_id"
+    t.index ["tag_id", "account_id"], name: "index_accounts_tags_on_tag_id_and_account_id", unique: true
+  end
+
   create_table "admin_action_logs", force: :cascade do |t|
     t.bigint "account_id"
     t.string "action", default: "", null: false
@@ -112,6 +179,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.bigint "target_account_id", null: false
     t.string "uri"
     t.index ["account_id", "target_account_id"], name: "index_blocks_on_account_id_and_target_account_id", unique: true
+    t.index ["target_account_id"], name: "index_blocks_on_target_account_id"
   end
 
   create_table "conversation_mutes", force: :cascade do |t|
@@ -149,9 +217,9 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.text "phrase", default: "", null: false
     t.string "context", default: [], null: false, array: true
     t.boolean "irreversible", default: false, null: false
-    t.boolean "whole_word", default: true, null: false
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.boolean "whole_word", default: true, null: false
     t.index ["account_id"], name: "index_custom_filters_on_account_id"
   end
 
@@ -161,6 +229,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.datetime "updated_at", null: false
     t.integer "severity", default: 0
     t.boolean "reject_media", default: false, null: false
+    t.boolean "reject_reports", default: false, null: false
     t.index ["domain"], name: "index_domain_blocks_on_domain", unique: true
   end
 
@@ -199,14 +268,15 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.boolean "show_reblogs", default: true, null: false
     t.string "uri"
     t.index ["account_id", "target_account_id"], name: "index_follows_on_account_id_and_target_account_id", unique: true
+    t.index ["target_account_id"], name: "index_follows_on_target_account_id"
   end
 
-  create_table "identities", id: :serial, force: :cascade do |t|
-    t.integer "user_id"
+  create_table "identities", force: :cascade do |t|
     t.string "provider", default: "", null: false
     t.string "uid", default: "", null: false
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.bigint "user_id"
     t.index ["user_id"], name: "index_identities_on_user_id"
   end
 
@@ -266,7 +336,9 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.json "file_meta"
     t.bigint "account_id"
     t.text "description"
+    t.bigint "scheduled_status_id"
     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
     t.index ["status_id"], name: "index_media_attachments_on_status_id"
   end
@@ -276,6 +348,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.bigint "account_id"
+    t.boolean "silent", default: false, null: false
     t.index ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true
     t.index ["status_id"], name: "index_mentions_on_status_id"
   end
@@ -287,6 +360,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     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
 
   create_table "notifications", force: :cascade do |t|
@@ -299,6 +373,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.index ["account_id", "activity_id", "activity_type"], name: "account_activity", unique: true
     t.index ["account_id", "id"], name: "index_notifications_on_account_id_and_id", order: { id: :desc }
     t.index ["activity_id", "activity_type"], name: "index_notifications_on_activity_id_and_activity_type"
+    t.index ["from_account_id"], name: "index_notifications_on_from_account_id"
   end
 
   create_table "oauth_access_grants", force: :cascade do |t|
@@ -310,6 +385,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.string "scopes"
     t.bigint "application_id", null: false
     t.bigint "resource_owner_id", null: false
+    t.index ["resource_owner_id"], name: "index_oauth_access_grants_on_resource_owner_id"
     t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true
   end
 
@@ -339,10 +415,20 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.string "website"
     t.string "owner_type"
     t.bigint "owner_id"
+    t.boolean "confidential", default: true, null: false
     t.index ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type"
     t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true
   end
 
+  create_table "pghero_space_stats", force: :cascade do |t|
+    t.text "database"
+    t.text "schema"
+    t.text "relation"
+    t.bigint "size"
+    t.datetime "captured_at"
+    t.index ["database", "captured_at"], name: "index_pghero_space_stats_on_database_and_captured_at"
+  end
+
   create_table "preview_cards", force: :cascade do |t|
     t.string "url", default: "", null: false
     t.string "title", default: "", null: false
@@ -371,6 +457,14 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.index ["status_id", "preview_card_id"], name: "index_preview_cards_statuses_on_status_id_and_preview_card_id"
   end
 
+  create_table "relays", force: :cascade do |t|
+    t.string "inbox_url", default: "", null: false
+    t.string "follow_activity_id"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.integer "state", default: 0, null: false
+  end
+
   create_table "report_notes", force: :cascade do |t|
     t.text "content", null: false
     t.bigint "report_id", null: false
@@ -395,6 +489,14 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.index ["target_account_id"], name: "index_reports_on_target_account_id"
   end
 
+  create_table "scheduled_statuses", force: :cascade do |t|
+    t.bigint "account_id"
+    t.datetime "scheduled_at"
+    t.jsonb "params"
+    t.index ["account_id"], name: "index_scheduled_statuses_on_account_id"
+    t.index ["scheduled_at"], name: "index_scheduled_statuses_on_scheduled_at"
+  end
+
   create_table "session_activations", force: :cascade do |t|
     t.string "session_id", null: false
     t.datetime "created_at", null: false
@@ -404,6 +506,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.bigint "access_token_id"
     t.bigint "user_id", null: false
     t.bigint "web_push_subscription_id"
+    t.index ["access_token_id"], name: "index_session_activations_on_access_token_id"
     t.index ["session_id"], name: "index_session_activations_on_session_id", unique: true
     t.index ["user_id"], name: "index_session_activations_on_user_id"
   end
@@ -438,6 +541,16 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.index ["account_id", "status_id"], name: "index_status_pins_on_account_id_and_status_id", unique: true
   end
 
+  create_table "status_stats", force: :cascade do |t|
+    t.bigint "status_id", null: false
+    t.bigint "replies_count", default: 0, null: false
+    t.bigint "reblogs_count", default: 0, null: false
+    t.bigint "favourites_count", default: 0, null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["status_id"], name: "index_status_stats_on_status_id", unique: true
+  end
+
   create_table "statuses", id: :bigint, default: -> { "timestamp_id('statuses'::text)" }, force: :cascade do |t|
     t.string "uri"
     t.text "text", default: "", null: false
@@ -450,8 +563,6 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.integer "visibility", default: 0, null: false
     t.text "spoiler_text", default: "", null: false
     t.boolean "reply", default: false, null: false
-    t.integer "favourites_count", default: 0, null: false
-    t.integer "reblogs_count", default: 0, null: false
     t.string "language"
     t.bigint "conversation_id"
     t.boolean "local"
@@ -459,6 +570,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.bigint "application_id"
     t.bigint "in_reply_to_account_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"
     t.index ["reblog_of_id", "account_id"], name: "index_statuses_on_reblog_of_id_and_account_id"
     t.index ["uri"], name: "index_statuses_on_uri", unique: true
@@ -503,6 +615,15 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.index ["name"], name: "index_tags_on_name", unique: true
   end
 
+  create_table "tombstones", force: :cascade do |t|
+    t.bigint "account_id"
+    t.string "uri", null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["account_id"], name: "index_tombstones_on_account_id"
+    t.index ["uri"], name: "index_tombstones_on_uri"
+  end
+
   create_table "users", force: :cascade do |t|
     t.string "email", default: "", null: false
     t.datetime "created_at", null: false
@@ -536,8 +657,10 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.bigint "invite_id"
     t.string "remember_token"
     t.string "chosen_languages", array: true
+    t.bigint "created_by_application_id"
     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"
     t.index ["email"], name: "index_users_on_email", unique: true
     t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
   end
@@ -563,9 +686,17 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
     t.index ["user_id"], name: "index_web_settings_on_user_id", unique: true
   end
 
+  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_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
+  add_foreign_key "account_pins", "accounts", on_delete: :cascade
+  add_foreign_key "account_stats", "accounts", on_delete: :cascade
+  add_foreign_key "account_tag_stats", "tags", on_delete: :cascade
+  add_foreign_key "account_warnings", "accounts", column: "target_account_id", on_delete: :cascade
+  add_foreign_key "account_warnings", "accounts", on_delete: :nullify
   add_foreign_key "accounts", "accounts", column: "moved_to_account_id", on_delete: :nullify
   add_foreign_key "admin_action_logs", "accounts", on_delete: :cascade
   add_foreign_key "backups", "users", on_delete: :nullify
@@ -580,7 +711,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
   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
   add_foreign_key "follows", "accounts", name: "fk_32ed1b5560", on_delete: :cascade
-  add_foreign_key "identities", "users", on_delete: :cascade
+  add_foreign_key "identities", "users", name: "fk_bea040f377", on_delete: :cascade
   add_foreign_key "imports", "accounts", name: "fk_6db1b6e408", on_delete: :cascade
   add_foreign_key "invites", "users", on_delete: :cascade
   add_foreign_key "list_accounts", "accounts", on_delete: :cascade
@@ -588,6 +719,7 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
   add_foreign_key "list_accounts", "lists", on_delete: :cascade
   add_foreign_key "lists", "accounts", on_delete: :cascade
   add_foreign_key "media_attachments", "accounts", name: "fk_96dd81e81b", on_delete: :nullify
+  add_foreign_key "media_attachments", "scheduled_statuses", on_delete: :nullify
   add_foreign_key "media_attachments", "statuses", on_delete: :nullify
   add_foreign_key "mentions", "accounts", name: "fk_970d43f9d1", on_delete: :cascade
   add_foreign_key "mentions", "statuses", on_delete: :cascade
@@ -606,10 +738,12 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
   add_foreign_key "reports", "accounts", column: "assigned_account_id", on_delete: :nullify
   add_foreign_key "reports", "accounts", column: "target_account_id", name: "fk_eb37af34f0", on_delete: :cascade
   add_foreign_key "reports", "accounts", name: "fk_4b81f7522c", on_delete: :cascade
+  add_foreign_key "scheduled_statuses", "accounts", on_delete: :cascade
   add_foreign_key "session_activations", "oauth_access_tokens", column: "access_token_id", name: "fk_957e5bda89", on_delete: :cascade
   add_foreign_key "session_activations", "users", name: "fk_e5fda67334", on_delete: :cascade
   add_foreign_key "status_pins", "accounts", name: "fk_d4cb435b62", on_delete: :cascade
   add_foreign_key "status_pins", "statuses", on_delete: :cascade
+  add_foreign_key "status_stats", "statuses", on_delete: :cascade
   add_foreign_key "statuses", "accounts", column: "in_reply_to_account_id", name: "fk_c7fa917661", on_delete: :nullify
   add_foreign_key "statuses", "accounts", name: "fk_9bda1543f7", on_delete: :cascade
   add_foreign_key "statuses", "statuses", column: "in_reply_to_id", on_delete: :nullify
@@ -618,8 +752,10 @@ ActiveRecord::Schema.define(version: 2018_07_07_154237) do
   add_foreign_key "statuses_tags", "tags", name: "fk_3081861e21", on_delete: :cascade
   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 "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
   add_foreign_key "web_push_subscriptions", "oauth_access_tokens", column: "access_token_id", on_delete: :cascade
   add_foreign_key "web_push_subscriptions", "users", on_delete: :cascade
   add_foreign_key "web_settings", "users", name: "fk_11910667b2", on_delete: :cascade
diff --git a/db/seeds.rb b/db/seeds.rb
index 6adfeed8d37afed26b8ec0a1d0a35cfd018953a3..cf62ebf39ad562f88247682f069c37f47bbb724d 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).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).save!
 end
diff --git a/dist/mastodon-sidekiq.service b/dist/mastodon-sidekiq.service
new file mode 100644
index 0000000000000000000000000000000000000000..721a8660902ef6cb1e5cf36edb61beeffdfbdaa8
--- /dev/null
+++ b/dist/mastodon-sidekiq.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=mastodon-sidekiq
+After=network.target
+
+[Service]
+Type=simple
+User=mastodon
+WorkingDirectory=/home/mastodon/live
+Environment="RAILS_ENV=production"
+Environment="DB_POOL=25"
+Environment="MALLOC_ARENA_MAX=2"
+ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 25
+TimeoutSec=15
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/dist/mastodon-streaming.service b/dist/mastodon-streaming.service
new file mode 100644
index 0000000000000000000000000000000000000000..5d7c129dfbbff5d17e7535f25982e351259fca01
--- /dev/null
+++ b/dist/mastodon-streaming.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=mastodon-streaming
+After=network.target
+
+[Service]
+Type=simple
+User=mastodon
+WorkingDirectory=/home/mastodon/live
+Environment="NODE_ENV=production"
+Environment="PORT=4000"
+Environment="STREAMING_CLUSTER_NUM=1"
+ExecStart=/usr/bin/npm run start
+TimeoutSec=15
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/dist/mastodon-web.service b/dist/mastodon-web.service
new file mode 100644
index 0000000000000000000000000000000000000000..30fcbec1e00603db49056779ee1015ba786170db
--- /dev/null
+++ b/dist/mastodon-web.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=mastodon-web
+After=network.target
+
+[Service]
+Type=simple
+User=mastodon
+WorkingDirectory=/home/mastodon/live
+Environment="RAILS_ENV=production"
+Environment="PORT=3000"
+ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
+ExecReload=/bin/kill -SIGUSR1 $MAINPID
+TimeoutSec=15
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/dist/nginx.conf b/dist/nginx.conf
new file mode 100644
index 0000000000000000000000000000000000000000..3d57417657002af4d722ee3cfa11d82b0afc03d6
--- /dev/null
+++ b/dist/nginx.conf
@@ -0,0 +1,106 @@
+map $http_upgrade $connection_upgrade {
+  default upgrade;
+  ''      close;
+}
+
+proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
+
+server {
+  listen 80;
+  listen [::]:80;
+  server_name example.com;
+  root /home/mastodon/live/public;
+  location /.well-known/acme-challenge/ { allow all; }
+  location / { return 301 https://$host$request_uri; }
+}
+
+server {
+  listen 443 ssl http2;
+  listen [::]:443 ssl http2;
+  server_name example.com;
+
+  ssl_protocols TLSv1.2;
+  ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
+  ssl_prefer_server_ciphers on;
+  ssl_session_cache shared:SSL:10m;
+
+  # Uncomment these lines once you acquire a certificate:
+  # ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
+  # ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
+
+  keepalive_timeout    70;
+  sendfile             on;
+  client_max_body_size 80m;
+
+  root /home/mastodon/live/public;
+
+  gzip on;
+  gzip_disable "msie6";
+  gzip_vary on;
+  gzip_proxied any;
+  gzip_comp_level 6;
+  gzip_buffers 16 8k;
+  gzip_http_version 1.1;
+  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
+
+  add_header Strict-Transport-Security "max-age=31536000";
+
+  location / {
+    try_files $uri @proxy;
+  }
+
+  location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
+    add_header Cache-Control "public, max-age=31536000, immutable";
+    add_header Strict-Transport-Security "max-age=31536000";
+    try_files $uri @proxy;
+  }
+
+  location /sw.js {
+    add_header Cache-Control "public, max-age=0";
+    add_header Strict-Transport-Security "max-age=31536000";
+    try_files $uri @proxy;
+  }
+
+  location @proxy {
+    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://127.0.0.1:3000;
+    proxy_buffering on;
+    proxy_redirect off;
+    proxy_http_version 1.1;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection $connection_upgrade;
+
+    proxy_cache CACHE;
+    proxy_cache_valid 200 7d;
+    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";
+
+    tcp_nodelay on;
+  }
+
+  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://127.0.0.1:4000;
+    proxy_buffering off;
+    proxy_redirect off;
+    proxy_http_version 1.1;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection $connection_upgrade;
+
+    tcp_nodelay on;
+  }
+
+  error_page 500 501 502 503 504 /500.html;
+}
diff --git a/docker-compose.yml b/docker-compose.yml
index c54c73e44a064cfddb0ac82b7024ed00a44a75c2..faa066149baf7938e027773ad8cab15e2146e203 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -6,18 +6,20 @@ services:
     image: postgres:9.6-alpine
     networks:
       - internal_network
-### Uncomment to enable DB persistance
-#    volumes:
-#      - ./postgres:/var/lib/postgresql/data
+    healthcheck:
+      test: ["CMD", "pg_isready", "-U", "postgres"]
+    volumes:
+      - ./postgres:/var/lib/postgresql/data
 
   redis:
     restart: always
     image: redis:4.0-alpine
     networks:
       - internal_network
-### Uncomment to enable REDIS persistance
-#    volumes:
-#      - ./redis:/data
+    healthcheck:
+      test: ["CMD", "redis-cli", "ping"]
+    volumes:
+      - ./redis:/data
 
 #  es:
 #    restart: always
@@ -26,9 +28,10 @@ services:
 #      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
 #    networks:
 #      - internal_network
-#### Uncomment to enable ES persistance
-##    volumes:
-##      - ./elasticsearch:/usr/share/elasticsearch/data
+#    healthcheck:
+#      test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
+#    volumes:
+#      - ./elasticsearch:/usr/share/elasticsearch/data
 
   web:
     build: .
@@ -39,6 +42,8 @@ services:
     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"]
     ports:
       - "127.0.0.1:3000:3000"
     depends_on:
@@ -46,8 +51,6 @@ services:
       - redis
 #      - es
     volumes:
-      - ./public/assets:/mastodon/public/assets
-      - ./public/packs:/mastodon/public/packs
       - ./public/system:/mastodon/public/system
 
   streaming:
@@ -59,6 +62,8 @@ services:
     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"]
     ports:
       - "127.0.0.1:4000:4000"
     depends_on:
@@ -70,7 +75,7 @@ services:
     image: tootsuite/mastodon
     restart: always
     env_file: .env.production
-    command: bundle exec sidekiq -q default -q mailers -q pull -q push
+    command: bundle exec sidekiq
     depends_on:
       - db
       - redis
@@ -78,20 +83,18 @@ services:
       - external_network
       - internal_network
     volumes:
-      - ./public/packs:/mastodon/public/packs
       - ./public/system:/mastodon/public/system
 ## Uncomment to enable federation with tor instances along with adding the following ENV variables
 ## http_proxy=http://privoxy:8118
 ## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
 #  tor:
-#    build: https://github.com/usbsnowcrash/docker-tor.git
+#    image: sirboops/tor
 #    networks:
 #      - external_network
 #      - internal_network
 #
 #  privoxy:
-#    build: https://github.com/usbsnowcrash/docker-privoxy.git
-#    command: /opt/sbin/privoxy --no-daemon --user privoxy.privoxy /opt/config
+#    image: sirboops/privoxy
 #    volumes:
 #      - ./priv-config:/opt/config
 #    networks:
diff --git a/docs/Contributing-to-Mastodon/Sponsors.md b/docs/Contributing-to-Mastodon/Sponsors.md
deleted file mode 100644
index 8fc22b6bbdde1fd7052a2eae1a30f735034487fb..0000000000000000000000000000000000000000
--- a/docs/Contributing-to-Mastodon/Sponsors.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Contributing-to-Mastodon/Sponsors.md)
diff --git a/docs/Contributing-to-Mastodon/Translating.md b/docs/Contributing-to-Mastodon/Translating.md
deleted file mode 100644
index 1671645eea4336ca660cdc6760233f66b10ebf07..0000000000000000000000000000000000000000
--- a/docs/Contributing-to-Mastodon/Translating.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Contributing-to-Mastodon/Translating.md)
diff --git a/docs/Extensions.md b/docs/Extensions.md
deleted file mode 100644
index be4c6eabd70e221070d1b89facddb83d4d2f1d66..0000000000000000000000000000000000000000
--- a/docs/Extensions.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Extensions.md)
diff --git a/docs/README.md b/docs/README.md
deleted file mode 100644
index 63bcf5a2480afc46cb2e37e38f233ea9f97286c1..0000000000000000000000000000000000000000
--- a/docs/README.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/README.md)
diff --git a/docs/Running-Mastodon/Administration-guide.md b/docs/Running-Mastodon/Administration-guide.md
deleted file mode 100644
index e7571be3a2709911825116c6ba548790fdb808f0..0000000000000000000000000000000000000000
--- a/docs/Running-Mastodon/Administration-guide.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Administration-guide.md)
diff --git a/docs/Running-Mastodon/Development-guide.md b/docs/Running-Mastodon/Development-guide.md
deleted file mode 100644
index 10ed6408750ef734ec77663c441816630f815bae..0000000000000000000000000000000000000000
--- a/docs/Running-Mastodon/Development-guide.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Development-guide.md)
diff --git a/docs/Running-Mastodon/Heroku-guide.md b/docs/Running-Mastodon/Heroku-guide.md
deleted file mode 100644
index aa5abc1f558b83a1f9db20627a3e24b93cacf08f..0000000000000000000000000000000000000000
--- a/docs/Running-Mastodon/Heroku-guide.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Heroku-guide.md)
diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md
deleted file mode 100644
index 08649e9ce5b8da2dc9c0406e801f40f93457803b..0000000000000000000000000000000000000000
--- a/docs/Running-Mastodon/Production-guide.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md)
diff --git a/docs/Running-Mastodon/Scalingo-guide.md b/docs/Running-Mastodon/Scalingo-guide.md
deleted file mode 100644
index 8c986f75091a75f1e98f9c6f4de48c3425243a26..0000000000000000000000000000000000000000
--- a/docs/Running-Mastodon/Scalingo-guide.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Scalingo-guide.md)
diff --git a/docs/Running-Mastodon/Tuning.md b/docs/Running-Mastodon/Tuning.md
deleted file mode 100644
index 5e5474194a5f01f98cbe13161243caec2f60e63b..0000000000000000000000000000000000000000
--- a/docs/Running-Mastodon/Tuning.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Tuning.md)
diff --git a/docs/Running-Mastodon/Vagrant-guide.md b/docs/Running-Mastodon/Vagrant-guide.md
deleted file mode 100644
index c5823b09b2d43f195924df86899488b3ba6cdfe6..0000000000000000000000000000000000000000
--- a/docs/Running-Mastodon/Vagrant-guide.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Vagrant-guide.md)
diff --git a/docs/Specs-and-RFCs-used.md b/docs/Specs-and-RFCs-used.md
deleted file mode 100644
index 89a4dd313efe43ea5cefeac76d973bc36cdbfdba..0000000000000000000000000000000000000000
--- a/docs/Specs-and-RFCs-used.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Specs-and-RFCs-used.md)
diff --git a/docs/Using-Mastodon/2FA.md b/docs/Using-Mastodon/2FA.md
deleted file mode 100644
index d5c6985b70ccfc8717c00f8a4fadb3f60079cca6..0000000000000000000000000000000000000000
--- a/docs/Using-Mastodon/2FA.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/2FA.md)
diff --git a/docs/Using-Mastodon/Apps.md b/docs/Using-Mastodon/Apps.md
deleted file mode 100644
index c2ced44576d978de1d6463d800bc54850e136779..0000000000000000000000000000000000000000
--- a/docs/Using-Mastodon/Apps.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md)
diff --git a/docs/Using-Mastodon/FAQ.md b/docs/Using-Mastodon/FAQ.md
deleted file mode 100644
index d50e63b93d040233877219d5fedc006e2b9e5096..0000000000000000000000000000000000000000
--- a/docs/Using-Mastodon/FAQ.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/FAQ.md)
diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md
deleted file mode 100644
index 0e2d08643eb245ce4789c4f02db6835076a9208c..0000000000000000000000000000000000000000
--- a/docs/Using-Mastodon/List-of-Mastodon-instances.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/List-of-Mastodon-instances.md)
diff --git a/docs/Using-Mastodon/User-guide.md b/docs/Using-Mastodon/User-guide.md
deleted file mode 100644
index 7ef5a117b08ea0baacc9f8677c2c585b206cde58..0000000000000000000000000000000000000000
--- a/docs/Using-Mastodon/User-guide.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/User-guide.md)
diff --git a/docs/Using-the-API/API.md b/docs/Using-the-API/API.md
deleted file mode 100644
index 6de61e19615c403bc95e9e80506904ca87fff22b..0000000000000000000000000000000000000000
--- a/docs/Using-the-API/API.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md)
diff --git a/docs/Using-the-API/OAuth-details.md b/docs/Using-the-API/OAuth-details.md
deleted file mode 100644
index 6a6926bb9cc06873971083936a6f45fb48b852b9..0000000000000000000000000000000000000000
--- a/docs/Using-the-API/OAuth-details.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-the-API/OAuth-details.md)
diff --git a/docs/Using-the-API/Push-notifications.md b/docs/Using-the-API/Push-notifications.md
deleted file mode 100644
index 3292c0a6e45fdd9c6811a904552874c9155245e8..0000000000000000000000000000000000000000
--- a/docs/Using-the-API/Push-notifications.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-the-API/Push-notifications.md)
diff --git a/docs/Using-the-API/Streaming-API.md b/docs/Using-the-API/Streaming-API.md
deleted file mode 100644
index 482f901c0f151cebcedd82a0f40aaf29eab068a6..0000000000000000000000000000000000000000
--- a/docs/Using-the-API/Streaming-API.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-the-API/Streaming-API.md)
diff --git a/docs/Using-the-API/Testing-with-cURL.md b/docs/Using-the-API/Testing-with-cURL.md
deleted file mode 100644
index 04c7c87b2defb0ed6220421508482f9c85bcc337..0000000000000000000000000000000000000000
--- a/docs/Using-the-API/Testing-with-cURL.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-the-API/Testing-with-cURL.md)
diff --git a/docs/Using-the-API/Tips-for-app-developers.md b/docs/Using-the-API/Tips-for-app-developers.md
deleted file mode 100644
index 36a28da2ea530485010360a9da3dead85ff3dafb..0000000000000000000000000000000000000000
--- a/docs/Using-the-API/Tips-for-app-developers.md
+++ /dev/null
@@ -1 +0,0 @@
-[The documentation has moved to its own repository](https://github.com/tootsuite/documentation/blob/master/Using-the-API/Tips-for-app-developers.md)
diff --git a/lib/cli.rb b/lib/cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6036adfbed7e03b1f9943d44793d2a15dca96138
--- /dev/null
+++ b/lib/cli.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'thor'
+require_relative 'mastodon/media_cli'
+require_relative 'mastodon/emoji_cli'
+require_relative 'mastodon/accounts_cli'
+require_relative 'mastodon/feeds_cli'
+require_relative 'mastodon/settings_cli'
+require_relative 'mastodon/domains_cli'
+require_relative 'mastodon/version'
+
+module Mastodon
+  class CLI < Thor
+    def self.exit_on_failure?
+      true
+    end
+
+    desc 'media SUBCOMMAND ...ARGS', 'Manage media files'
+    subcommand 'media', Mastodon::MediaCLI
+
+    desc 'emoji SUBCOMMAND ...ARGS', 'Manage custom emoji'
+    subcommand 'emoji', Mastodon::EmojiCLI
+
+    desc 'accounts SUBCOMMAND ...ARGS', 'Manage accounts'
+    subcommand 'accounts', Mastodon::AccountsCLI
+
+    desc 'feeds SUBCOMMAND ...ARGS', 'Manage feeds'
+    subcommand 'feeds', Mastodon::FeedsCLI
+
+    desc 'settings SUBCOMMAND ...ARGS', 'Manage dynamic settings'
+    subcommand 'settings', Mastodon::SettingsCLI
+
+    desc 'domains SUBCOMMAND ...ARGS', 'Manage account domains'
+    subcommand 'domains', Mastodon::DomainsCLI
+
+    map %w(--version -v) => :version
+
+    desc 'version', 'Show version'
+    def version
+      say(Mastodon::Version.to_s)
+    end
+  end
+end
diff --git a/lib/devise/ldap_authenticatable.rb b/lib/devise/ldap_authenticatable.rb
index ef786fbb77a26674ae1df42f3cf7a4c0d371243e..6903d468dc4958a8d2cf504f626e3f3871591be4 100644
--- a/lib/devise/ldap_authenticatable.rb
+++ b/lib/devise/ldap_authenticatable.rb
@@ -24,11 +24,13 @@ module Devise
             connect_timeout: 10
           )
 
-          if (user_info = ldap.bind_as(base: Devise.ldap_base, filter: "(#{Devise.ldap_uid}=#{email})", password: password))
+          filter = format(Devise.ldap_search_filter, uid: Devise.ldap_uid, email: email)
+
+          if (user_info = ldap.bind_as(base: Devise.ldap_base, filter: filter, password: password))
             user = User.ldap_get_user(user_info.first)
             success!(user)
           else
-            return fail(:invalid_login)
+            return fail(:invalid)
           end
         end
       end
diff --git a/lib/generators/post_deployment_migration_generator.rb b/lib/generators/post_deployment_migration_generator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..798c01b883ac46814338c1b8049ceb610d8e1776
--- /dev/null
+++ b/lib/generators/post_deployment_migration_generator.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'rails/generators'
+
+module Rails
+  class PostDeploymentMigrationGenerator < Rails::Generators::NamedBase
+    def create_migration_file
+      timestamp = Time.zone.now.strftime('%Y%m%d%H%M%S')
+
+      template 'migration.rb', "db/post_migrate/#{timestamp}_#{file_name}.rb"
+    end
+
+    def migration_class_name
+      file_name.camelize
+    end
+  end
+end
diff --git a/lib/json_ld/security.rb b/lib/json_ld/security.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1230206f035d1e315fec6522ac06eab6877163a5
--- /dev/null
+++ b/lib/json_ld/security.rb
@@ -0,0 +1,50 @@
+# -*- encoding: utf-8 -*-
+# frozen_string_literal: true
+# This file generated automatically from https://w3id.org/security/v1
+require 'json/ld'
+class JSON::LD::Context
+  add_preloaded("https://w3id.org/security/v1") do
+    new(processingMode: "json-ld-1.0", term_definitions: {
+      "CryptographicKey" => TermDefinition.new("CryptographicKey", id: "https://w3id.org/security#Key", simple: true),
+      "EcdsaKoblitzSignature2016" => TermDefinition.new("EcdsaKoblitzSignature2016", id: "https://w3id.org/security#EcdsaKoblitzSignature2016", simple: true),
+      "EncryptedMessage" => TermDefinition.new("EncryptedMessage", id: "https://w3id.org/security#EncryptedMessage", simple: true),
+      "GraphSignature2012" => TermDefinition.new("GraphSignature2012", id: "https://w3id.org/security#GraphSignature2012", simple: true),
+      "LinkedDataSignature2015" => TermDefinition.new("LinkedDataSignature2015", id: "https://w3id.org/security#LinkedDataSignature2015", simple: true),
+      "LinkedDataSignature2016" => TermDefinition.new("LinkedDataSignature2016", id: "https://w3id.org/security#LinkedDataSignature2016", simple: true),
+      "authenticationTag" => TermDefinition.new("authenticationTag", id: "https://w3id.org/security#authenticationTag", simple: true),
+      "canonicalizationAlgorithm" => TermDefinition.new("canonicalizationAlgorithm", id: "https://w3id.org/security#canonicalizationAlgorithm", simple: true),
+      "cipherAlgorithm" => TermDefinition.new("cipherAlgorithm", id: "https://w3id.org/security#cipherAlgorithm", simple: true),
+      "cipherData" => TermDefinition.new("cipherData", id: "https://w3id.org/security#cipherData", simple: true),
+      "cipherKey" => TermDefinition.new("cipherKey", id: "https://w3id.org/security#cipherKey", simple: true),
+      "created" => TermDefinition.new("created", id: "http://purl.org/dc/terms/created", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
+      "creator" => TermDefinition.new("creator", id: "http://purl.org/dc/terms/creator", type_mapping: "@id"),
+      "dc" => TermDefinition.new("dc", id: "http://purl.org/dc/terms/", simple: true, prefix: true),
+      "digestAlgorithm" => TermDefinition.new("digestAlgorithm", id: "https://w3id.org/security#digestAlgorithm", simple: true),
+      "digestValue" => TermDefinition.new("digestValue", id: "https://w3id.org/security#digestValue", simple: true),
+      "domain" => TermDefinition.new("domain", id: "https://w3id.org/security#domain", simple: true),
+      "encryptionKey" => TermDefinition.new("encryptionKey", id: "https://w3id.org/security#encryptionKey", simple: true),
+      "expiration" => TermDefinition.new("expiration", id: "https://w3id.org/security#expiration", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
+      "expires" => TermDefinition.new("expires", id: "https://w3id.org/security#expiration", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
+      "id" => TermDefinition.new("id", id: "@id", simple: true),
+      "initializationVector" => TermDefinition.new("initializationVector", id: "https://w3id.org/security#initializationVector", simple: true),
+      "iterationCount" => TermDefinition.new("iterationCount", id: "https://w3id.org/security#iterationCount", simple: true),
+      "nonce" => TermDefinition.new("nonce", id: "https://w3id.org/security#nonce", simple: true),
+      "normalizationAlgorithm" => TermDefinition.new("normalizationAlgorithm", id: "https://w3id.org/security#normalizationAlgorithm", simple: true),
+      "owner" => TermDefinition.new("owner", id: "https://w3id.org/security#owner", type_mapping: "@id"),
+      "password" => TermDefinition.new("password", id: "https://w3id.org/security#password", simple: true),
+      "privateKey" => TermDefinition.new("privateKey", id: "https://w3id.org/security#privateKey", type_mapping: "@id"),
+      "privateKeyPem" => TermDefinition.new("privateKeyPem", id: "https://w3id.org/security#privateKeyPem", simple: true),
+      "publicKey" => TermDefinition.new("publicKey", id: "https://w3id.org/security#publicKey", type_mapping: "@id"),
+      "publicKeyPem" => TermDefinition.new("publicKeyPem", id: "https://w3id.org/security#publicKeyPem", simple: true),
+      "publicKeyService" => TermDefinition.new("publicKeyService", id: "https://w3id.org/security#publicKeyService", type_mapping: "@id"),
+      "revoked" => TermDefinition.new("revoked", id: "https://w3id.org/security#revoked", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
+      "salt" => TermDefinition.new("salt", id: "https://w3id.org/security#salt", simple: true),
+      "sec" => TermDefinition.new("sec", id: "https://w3id.org/security#", simple: true, prefix: true),
+      "signature" => TermDefinition.new("signature", id: "https://w3id.org/security#signature", simple: true),
+      "signatureAlgorithm" => TermDefinition.new("signatureAlgorithm", id: "https://w3id.org/security#signingAlgorithm", simple: true),
+      "signatureValue" => TermDefinition.new("signatureValue", id: "https://w3id.org/security#signatureValue", simple: true),
+      "type" => TermDefinition.new("type", id: "@type", simple: true),
+      "xsd" => TermDefinition.new("xsd", id: "http://www.w3.org/2001/XMLSchema#", simple: true, prefix: true)
+    })
+  end
+end
diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dca31cdca3e7bf4840ddb955662de4b0c578e8bd
--- /dev/null
+++ b/lib/mastodon/accounts_cli.rb
@@ -0,0 +1,377 @@
+# frozen_string_literal: true
+
+require 'set'
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class AccountsCLI < Thor
+    def self.exit_on_failure?
+      true
+    end
+
+    option :all, type: :boolean
+    desc 'rotate [USERNAME]', 'Generate and broadcast new keys'
+    long_desc <<-LONG_DESC
+      Generate and broadcast new RSA keys as part of security
+      maintenance.
+
+      With the --all option, all local accounts will be subject
+      to the rotation. Otherwise, and by default, only a single
+      account specified by the USERNAME argument will be
+      processed.
+    LONG_DESC
+    def rotate(username = nil)
+      if options[:all]
+        processed = 0
+        delay     = 0
+
+        Account.local.without_suspended.find_in_batches do |accounts|
+          accounts.each do |account|
+            rotate_keys_for_account(account, delay)
+            processed += 1
+            say('.', :green, false)
+          end
+
+          delay += 5.minutes
+        end
+
+        say
+        say("OK, rotated keys for #{processed} accounts", :green)
+      elsif username.present?
+        rotate_keys_for_account(Account.find_local(username))
+        say('OK', :green)
+      else
+        say('No account(s) given', :red)
+        exit(1)
+      end
+    end
+
+    option :email, required: true
+    option :confirmed, type: :boolean
+    option :role, default: 'user'
+    option :reattach, type: :boolean
+    option :force, type: :boolean
+    desc 'create USERNAME', 'Create a new user'
+    long_desc <<-LONG_DESC
+      Create a new user account with a given USERNAME and an
+      e-mail address provided with --email.
+
+      With the --confirmed option, the confirmation e-mail will
+      be skipped and the account will be active straight away.
+
+      With the --role option one of  "user", "admin" or "moderator"
+      can be supplied. Defaults to "user"
+
+      With the --reattach option, the new user will be reattached
+      to a given existing username of an old account. If the old
+      account is still in use by someone else, you can supply
+      the --force option to delete the old record and reattach the
+      username to the new account anyway.
+    LONG_DESC
+    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)
+
+      if options[:reattach]
+        account = Account.find_local(username) || Account.new(username: username)
+
+        if account.user.present? && !options[:force]
+          say('The chosen username is currently in use', :red)
+          say('Use --force to reattach it anyway and delete the other user')
+          return
+        elsif account.user.present?
+          account.user.destroy!
+        end
+      end
+
+      account.suspended = false
+      user.account      = account
+
+      if user.save
+        if options[:confirmed]
+          user.confirmed_at = nil
+          user.confirm!
+        end
+
+        say('OK', :green)
+        say("New password: #{password}")
+      else
+        user.errors.to_h.each do |key, error|
+          say('Failure/Error: ', :red)
+          say(key)
+          say('    ' + error, :red)
+        end
+
+        exit(1)
+      end
+    end
+
+    option :role
+    option :email
+    option :confirm, type: :boolean
+    option :enable, type: :boolean
+    option :disable, type: :boolean
+    option :disable_2fa, type: :boolean
+    desc 'modify USERNAME', 'Modify a user'
+    long_desc <<-LONG_DESC
+      Modify a user account.
+
+      With the --role option, update the user's role to one of "user",
+      "moderator" or "admin".
+
+      With the --email option, update the user's e-mail address. With
+      the --confirm option, mark the user's e-mail as confirmed.
+
+      With the --disable option, lock the user out of their account. The
+      --enable option is the opposite.
+
+      With the --disable-2fa option, the two-factor authentication
+      requirement for the user can be removed.
+    LONG_DESC
+    def modify(username)
+      user = Account.find_local(username)&.user
+
+      if user.nil?
+        say('No user with such username', :red)
+        exit(1)
+      end
+
+      if options[:role]
+        user.admin = options[:role] == 'admin'
+        user.moderator = options[:role] == 'moderator'
+      end
+
+      user.email = options[:email] if options[:email]
+      user.disabled = false if options[:enable]
+      user.disabled = true if options[:disable]
+      user.otp_required_for_login = false if options[:disable_2fa]
+      user.confirm if options[:confirm]
+
+      if user.save
+        say('OK', :green)
+      else
+        user.errors.to_h.each do |key, error|
+          say('Failure/Error: ', :red)
+          say(key)
+          say('    ' + error, :red)
+        end
+
+        exit(1)
+      end
+    end
+
+    desc 'delete USERNAME', 'Delete a user'
+    long_desc <<-LONG_DESC
+      Remove a user account with a given USERNAME.
+    LONG_DESC
+    def delete(username)
+      account = Account.find_local(username)
+
+      if account.nil?
+        say('No user with such username', :red)
+        exit(1)
+      end
+
+      say("Deleting user with #{account.statuses_count} statuses, this might take a while...")
+      SuspendAccountService.new.call(account, including_user: true)
+      say('OK', :green)
+    end
+
+    desc 'backup USERNAME', 'Request a backup for a user'
+    long_desc <<-LONG_DESC
+      Request a new backup for an account with a given USERNAME.
+
+      The backup will be created in Sidekiq asynchronously, and
+      the user will receive an e-mail with a link to it once
+      it's done.
+    LONG_DESC
+    def backup(username)
+      account = Account.find_local(username)
+
+      if account.nil?
+        say('No user with such username', :red)
+        exit(1)
+      end
+
+      backup = account.user.backups.create!
+      BackupWorker.perform_async(backup.id)
+      say('OK', :green)
+    end
+
+    option :dry_run, type: :boolean
+    desc 'cull', 'Remove remote accounts that no longer exist'
+    long_desc <<-LONG_DESC
+      Query every single remote account in the database to determine
+      if it still exists on the origin server, and if it doesn't,
+      remove it from the database.
+
+      Accounts that have had confirmed activity within the last week
+      are excluded from the checks.
+
+      Domains that are unreachable are not checked.
+
+      With the --dry-run option, no deletes will actually be carried
+      out.
+    LONG_DESC
+    def cull
+      skip_threshold = 7.days.ago
+      culled         = 0
+      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)
+
+        unless skip_domains.include?(account.domain)
+          begin
+            code = Request.new(:head, account.uri).perform(&:code)
+          rescue HTTP::ConnectionError
+            skip_domains << account.domain
+          rescue StandardError
+            next
+          end
+        end
+
+        if [404, 410].include?(code)
+          unless options[:dry_run]
+            SuspendAccountService.new.call(account)
+            account.destroy
+          end
+
+          culled += 1
+          say('+', :green, false)
+        else
+          account.touch # Touch account even during dry run to avoid getting the account into the window again
+          say('.', nil, false)
+        end
+      end
+
+      say
+      say("Removed #{culled} accounts. #{skip_domains.size} servers skipped#{dry_run}", skip_domains.empty? ? :green : :yellow)
+
+      unless skip_domains.empty?
+        say('The following servers were not available during the check:', :yellow)
+        skip_domains.each { |domain| say('    ' + domain) }
+      end
+    end
+
+    option :all, type: :boolean
+    option :domain
+    desc 'refresh [USERNAME]', 'Fetch remote user data and files'
+    long_desc <<-LONG_DESC
+      Fetch remote user data and files for one or multiple accounts.
+
+      With the --all option, all remote accounts will be processed.
+      Through the --domain option, this can be narrowed down to a
+      specific domain only. Otherwise, a single remote account must
+      be specified with USERNAME.
+
+      All processing is done in the background through Sidekiq.
+    LONG_DESC
+    def refresh(username = nil)
+      if options[:domain] || options[:all]
+        queued = 0
+        scope  = Account.remote
+        scope  = scope.where(domain: options[:domain]) if options[:domain]
+
+        scope.select(:id).reorder(nil).find_in_batches do |accounts|
+          Maintenance::RedownloadAccountMediaWorker.push_bulk(accounts.map(&:id))
+          queued += accounts.size
+        end
+
+        say("Scheduled refreshment of #{queued} accounts", :green, true)
+      elsif username.present?
+        username, domain = username.split('@')
+        account = Account.find_remote(username, domain)
+
+        if account.nil?
+          say('No such account', :red)
+          exit(1)
+        end
+
+        Maintenance::RedownloadAccountMediaWorker.perform_async(account.id)
+        say('OK', :green)
+      else
+        say('No account(s) given', :red)
+        exit(1)
+      end
+    end
+
+    desc 'follow ACCT', 'Make all local accounts follow account specified by ACCT'
+    long_desc <<-LONG_DESC
+      Make all local accounts follow an account specified by ACCT. ACCT can be
+      a simple username, in case of a local user. It can also be in the format
+      username@domain, in case of a remote user.
+    LONG_DESC
+    def follow(acct)
+      target_account = ResolveAccountService.new.call(acct)
+      processed      = 0
+      failed         = 0
+
+      if target_account.nil?
+        say("Target account (#{acct}) could not be resolved", :red)
+        exit(1)
+      end
+
+      Account.local.without_suspended.find_each do |account|
+        begin
+          FollowService.new.call(account, target_account)
+          processed += 1
+          say('.', :green, false)
+        rescue StandardError
+          failed += 1
+          say('.', :red, false)
+        end
+      end
+
+      say("OK, followed target from #{processed} accounts, skipped #{failed}", :green)
+    end
+
+    desc 'unfollow ACCT', 'Make all local accounts unfollow account specified by ACCT'
+    long_desc <<-LONG_DESC
+      Make all local accounts unfollow an account specified by ACCT. ACCT can be
+      a simple username, in case of a local user. It can also be in the format
+      username@domain, in case of a remote user.
+    LONG_DESC
+    def unfollow(acct)
+      target_account = Account.find_remote(*acct.split('@'))
+      processed      = 0
+      failed         = 0
+
+      if target_account.nil?
+        say("Target account (#{acct}) was not found", :red)
+        exit(1)
+      end
+
+      target_account.followers.local.find_each do |account|
+        begin
+          UnfollowService.new.call(account, target_account)
+          processed += 1
+          say('.', :green, false)
+        rescue StandardError
+          failed += 1
+          say('.', :red, false)
+        end
+      end
+
+      say("OK, unfollowed target from #{processed} accounts, skipped #{failed}", :green)
+    end
+
+    private
+
+    def rotate_keys_for_account(account, delay = 0)
+      if account.nil?
+        say('No such account', :red)
+        exit(1)
+      end
+
+      old_key = account.private_key
+      new_key = OpenSSL::PKey::RSA.new(2048)
+      account.update(private_key: new_key.to_pem, public_key: new_key.public_key.to_pem)
+      ActivityPub::UpdateDistributionWorker.perform_in(delay, account.id, sign_with: old_key)
+    end
+  end
+end
diff --git a/lib/mastodon/cli_helper.rb b/lib/mastodon/cli_helper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2f807d08c84f94dbefc9f304dcff4dc8616cd6f8
--- /dev/null
+++ b/lib/mastodon/cli_helper.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+dev_null = Logger.new('/dev/null')
+
+Rails.logger                 = dev_null
+ActiveRecord::Base.logger    = dev_null
+ActiveJob::Base.logger       = dev_null
+HttpLog.configuration.logger = dev_null
+Paperclip.options[:log]      = false
diff --git a/lib/mastodon/domains_cli.rb b/lib/mastodon/domains_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..303b8a94a0f0be6cf5eaaed54dcb2421375152fb
--- /dev/null
+++ b/lib/mastodon/domains_cli.rb
@@ -0,0 +1,147 @@
+# frozen_string_literal: true
+
+require 'concurrent'
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class DomainsCLI < Thor
+    def self.exit_on_failure?
+      true
+    end
+
+    option :dry_run, type: :boolean
+    desc 'purge DOMAIN', 'Remove accounts from a DOMAIN without a trace'
+    long_desc <<-LONG_DESC
+      Remove all accounts from a given DOMAIN without leaving behind any
+      records. Unlike a suspension, if the DOMAIN still exists in the wild,
+      it means the accounts could return if they are resolved again.
+    LONG_DESC
+    def purge(domain)
+      removed = 0
+      dry_run = options[:dry_run] ? ' (DRY RUN)' : ''
+
+      Account.where(domain: domain).find_each do |account|
+        SuspendAccountService.new.call(account, destroy: true) unless options[:dry_run]
+        removed += 1
+        say('.', :green, false)
+      end
+
+      DomainBlock.where(domain: domain).destroy_all
+
+      say
+      say("Removed #{removed} accounts#{dry_run}", :green)
+    end
+
+    option :concurrency, type: :numeric, default: 50, aliases: [:c]
+    option :silent, type: :boolean, default: false, aliases: [:s]
+    option :format, type: :string, default: 'summary', aliases: [:f]
+    desc 'crawl [START]', 'Crawl all known peers, optionally beginning at START'
+    long_desc <<-LONG_DESC
+      Crawl the fediverse by using the Mastodon REST API endpoints that expose
+      all known peers, and collect statistics from those peers, as long as those
+      peers support those API endpoints. When no START is given, the command uses
+      this server's own database of known peers to seed the crawl.
+
+      The --concurrency (-c) option controls the number of threads performing HTTP
+      requests at the same time. More threads means the crawl may complete faster.
+
+      The --silent (-s) option controls progress output.
+
+      The --format (-f) option controls how the data is displayed at the end. By
+      default (`summary`), a summary of the statistics is returned. The other options
+      are `domains`, which returns a newline-delimited list of all discovered peers,
+      and `json`, which dumps all the aggregated data raw.
+    LONG_DESC
+    def crawl(start = nil)
+      stats     = Concurrent::Hash.new
+      processed = Concurrent::AtomicFixnum.new(0)
+      failed    = Concurrent::AtomicFixnum.new(0)
+      start_at  = Time.now.to_f
+      seed      = start ? [start] : Account.remote.domains
+
+      pool = Concurrent::ThreadPoolExecutor.new(min_threads: 0, max_threads: options[:concurrency], idletime: 10, auto_terminate: true, max_queue: 0)
+
+      work_unit = ->(domain) do
+        next if stats.key?(domain)
+        stats[domain] = nil
+        processed.increment
+
+        begin
+          Request.new(:get, "https://#{domain}/api/v1/instance").perform do |res|
+            next unless res.code == 200
+            stats[domain] = Oj.load(res.to_s)
+          end
+
+          Request.new(:get, "https://#{domain}/api/v1/instance/peers").perform do |res|
+            next unless res.code == 200
+
+            Oj.load(res.to_s).reject { |peer| stats.key?(peer) }.each do |peer|
+              pool.post(peer, &work_unit)
+            end
+          end
+
+          Request.new(:get, "https://#{domain}/api/v1/instance/activity").perform do |res|
+            next unless res.code == 200
+            stats[domain]['activity'] = Oj.load(res.to_s)
+          end
+
+          say('.', :green, false) unless options[:silent]
+        rescue StandardError
+          failed.increment
+          say('.', :red, false) unless options[:silent]
+        end
+      end
+
+      seed.each do |domain|
+        pool.post(domain, &work_unit)
+      end
+
+      sleep 20
+      sleep 20 until pool.queue_length.zero?
+
+      pool.shutdown
+      pool.wait_for_termination(20)
+    ensure
+      pool.shutdown
+
+      say unless options[:silent]
+
+      case options[:format]
+      when 'summary'
+        stats_to_summary(stats, processed, failed, start_at)
+      when 'domains'
+        stats_to_domains(stats)
+      when 'json'
+        stats_to_json(stats)
+      end
+    end
+
+    private
+
+    def stats_to_summary(stats, processed, failed, start_at)
+      stats.compact!
+
+      total_domains = stats.size
+      total_users   = stats.reduce(0) { |sum, (_key, val)| val.is_a?(Hash) && val['stats'].is_a?(Hash) ? sum + val['stats']['user_count'].to_i : sum }
+      total_active  = stats.reduce(0) { |sum, (_key, val)| val.is_a?(Hash) && val['activity'].is_a?(Array) && val['activity'].size > 2 && val['activity'][1].is_a?(Hash) ? sum + val['activity'][1]['logins'].to_i : sum }
+      total_joined  = stats.reduce(0) { |sum, (_key, val)| val.is_a?(Hash) && val['activity'].is_a?(Array) && val['activity'].size > 2 && val['activity'][1].is_a?(Hash) ? sum + val['activity'][1]['registrations'].to_i : sum }
+
+      say("Visited #{processed.value} domains, #{failed.value} failed (#{(Time.now.to_f - start_at).round}s elapsed)", :green)
+      say("Total servers: #{total_domains}", :green)
+      say("Total registered: #{total_users}", :green)
+      say("Total active last week: #{total_active}", :green)
+      say("Total joined last week: #{total_joined}", :green)
+    end
+
+    def stats_to_domains(stats)
+      say(stats.keys.join("\n"))
+    end
+
+    def stats_to_json(stats)
+      stats.compact!
+      say(Oj.dump(stats))
+    end
+  end
+end
diff --git a/lib/mastodon/emoji_cli.rb b/lib/mastodon/emoji_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2262040d49cbb0f0e3f8c0fc8e1a07e36497da3e
--- /dev/null
+++ b/lib/mastodon/emoji_cli.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'rubygems/package'
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class EmojiCLI < Thor
+    def self.exit_on_failure?
+      true
+    end
+
+    option :prefix
+    option :suffix
+    option :overwrite, type: :boolean
+    option :unlisted, type: :boolean
+    desc 'import PATH', 'Import emoji from a TAR archive at PATH'
+    long_desc <<-LONG_DESC
+      Imports custom emoji from a TAR archive specified by PATH.
+
+      Existing emoji will be skipped unless the --overwrite option
+      is provided, in which case they will be overwritten.
+
+      With the --prefix option, a prefix can be added to all
+      generated shortcodes. Likewise, the --suffix option controls
+      the suffix of all shortcodes.
+
+      With the --unlisted option, the processed emoji will not be
+      visible in the emoji picker (but still usable via other means)
+    LONG_DESC
+    def import(path)
+      imported = 0
+      skipped  = 0
+      failed   = 0
+
+      Gem::Package::TarReader.new(Zlib::GzipReader.open(path)) do |tar|
+        tar.each do |entry|
+          next unless entry.file? && entry.full_name.end_with?('.png')
+
+          shortcode    = [options[:prefix], File.basename(entry.full_name, '.*'), options[:suffix]].compact.join
+          custom_emoji = CustomEmoji.local.find_by(shortcode: shortcode)
+
+          if custom_emoji && !options[:overwrite]
+            skipped += 1
+            next
+          end
+
+          custom_emoji ||= CustomEmoji.new(shortcode: shortcode, domain: nil)
+          custom_emoji.image = StringIO.new(entry.read)
+          custom_emoji.image_file_name = File.basename(entry.full_name)
+          custom_emoji.visible_in_picker = !options[:unlisted]
+
+          if custom_emoji.save
+            imported += 1
+          else
+            failed += 1
+            say('Failure/Error: ', :red)
+            say(entry.full_name)
+            say('    ' + custom_emoji.errors[:image].join(', '), :red)
+          end
+        end
+      end
+
+      puts
+      say("Imported #{imported}, skipped #{skipped}, failed to import #{failed}", color(imported, skipped, failed))
+    end
+
+    private
+
+    def color(green, _yellow, red)
+      if !green.zero? && red.zero?
+        :green
+      elsif red.zero?
+        :yellow
+      else
+        :red
+      end
+    end
+  end
+end
diff --git a/lib/mastodon/feeds_cli.rb b/lib/mastodon/feeds_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fe11c3df400c1890d8d20b61911a11064b01b0be
--- /dev/null
+++ b/lib/mastodon/feeds_cli.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class FeedsCLI < Thor
+    def self.exit_on_failure?
+      true
+    end
+
+    option :all, type: :boolean, default: false
+    option :background, type: :boolean, default: false
+    option :dry_run, type: :boolean, default: false
+    option :verbose, type: :boolean, default: false
+    desc 'build [USERNAME]', 'Build home and list feeds for one or all users'
+    long_desc <<-LONG_DESC
+      Build home and list feeds that are stored in Redis from the database.
+
+      With the --all option, all active users will be processed.
+      Otherwise, a single user specified by USERNAME.
+
+      With the --background option, regeneration will be queued into Sidekiq,
+      and the command will exit as soon as possible.
+
+      With the --dry-run option, no work will be done.
+
+      With the --verbose option, when accounts are processed sequentially in the
+      foreground, the IDs of the accounts will be printed.
+    LONG_DESC
+    def build(username = nil)
+      dry_run = options[:dry_run] ? '(DRY RUN)' : ''
+
+      if options[:all] || username.nil?
+        processed = 0
+        queued    = 0
+
+        User.active.select(:id, :account_id).reorder(nil).find_in_batches do |users|
+          if options[:background]
+            RegenerationWorker.push_bulk(users.map(&:account_id)) unless options[:dry_run]
+            queued += users.size
+          else
+            users.each do |user|
+              RegenerationWorker.new.perform(user.account_id) unless options[:dry_run]
+              options[:verbose] ? say(user.account_id) : say('.', :green, false)
+              processed += 1
+            end
+          end
+        end
+
+        if options[:background]
+          say("Scheduled feed regeneration for #{queued} accounts #{dry_run}", :green, true)
+        else
+          say
+          say("Regenerated feeds for #{processed} accounts #{dry_run}", :green, true)
+        end
+      elsif username.present?
+        account = Account.find_local(username)
+
+        if account.nil?
+          say('No such account', :red)
+          exit(1)
+        end
+
+        if options[:background]
+          RegenerationWorker.perform_async(account.id) unless options[:dry_run]
+        else
+          RegenerationWorker.new.perform(account.id) unless options[:dry_run]
+        end
+
+        say("OK #{dry_run}", :green, true)
+      else
+        say('No account(s) given', :red)
+        exit(1)
+      end
+    end
+
+    desc 'clear', 'Remove all home and list feeds from Redis'
+    def clear
+      keys = Redis.current.keys('feed:*')
+
+      Redis.current.pipelined do
+        keys.each { |key| Redis.current.del(key) }
+      end
+
+      say('OK', :green)
+    end
+  end
+end
diff --git a/lib/mastodon/media_cli.rb b/lib/mastodon/media_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6152d5a0950ccaf42502d6b0ca5908abaec65290
--- /dev/null
+++ b/lib/mastodon/media_cli.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class MediaCLI < Thor
+    include ActionView::Helpers::NumberHelper
+
+    def self.exit_on_failure?
+      true
+    end
+
+    option :days, type: :numeric, default: 7
+    option :background, type: :boolean, default: false
+    option :verbose, type: :boolean, default: false
+    option :dry_run, type: :boolean, default: false
+    desc 'remove', 'Remove remote media files'
+    long_desc <<-DESC
+      Removes locally cached copies of media attachments from other servers.
+
+      The --days option specifies how old media attachments have to be before
+      they are removed. It defaults to 7 days.
+
+      With the --background option, instead of deleting the files sequentially,
+      they will be queued into Sidekiq and the command will exit as soon as
+      possible. In Sidekiq they will be processed with higher concurrency, but
+      it may impact other operations of the Mastodon server, and it may overload
+      the underlying file storage.
+
+      With the --dry-run option, no work will be done.
+
+      With the --verbose option, when media attachments are processed sequentially in the
+      foreground, the IDs of the media attachments will be printed.
+    DESC
+    def remove
+      time_ago  = options[:days].days.ago
+      queued    = 0
+      processed = 0
+      size      = 0
+      dry_run   = options[:dry_run] ? '(DRY RUN)' : ''
+
+      if options[:background]
+        MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).select(:id, :file_file_size).reorder(nil).find_in_batches do |media_attachments|
+          queued += media_attachments.size
+          size   += media_attachments.reduce(0) { |sum, m| sum + (m.file_file_size || 0) }
+          Maintenance::UncacheMediaWorker.push_bulk(media_attachments.map(&:id)) unless options[:dry_run]
+        end
+      else
+        MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).reorder(nil).find_in_batches do |media_attachments|
+          media_attachments.each do |m|
+            size += m.file_file_size || 0
+            Maintenance::UncacheMediaWorker.new.perform(m) unless options[:dry_run]
+            options[:verbose] ? say(m.id) : say('.', :green, false)
+            processed += 1
+          end
+        end
+      end
+
+      say
+
+      if options[:background]
+        say("Scheduled the deletion of #{queued} media attachments (approx. #{number_to_human_size(size)}) #{dry_run}", :green, true)
+      else
+        say("Removed #{processed} media attachments (approx. #{number_to_human_size(size)}) #{dry_run}", :green, true)
+      end
+    end
+  end
+end
diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb
index e154b5a2cd7cd0b2194eef1cadf190300623777d..f5dc7e1c6ec15c3613a36212bf2f99f303077614 100644
--- a/lib/mastodon/migration_helpers.rb
+++ b/lib/mastodon/migration_helpers.rb
@@ -342,8 +342,8 @@ module Mastodon
 
       say "Migrating #{table_name}.#{column} (~#{total.to_i} rows)"
 
-      started_time = Time.now
-      last_time = Time.now
+      started_time = Time.zone.now
+      last_time = Time.zone.now
       migrated = 0
       loop do
         stop_row = nil
@@ -375,13 +375,13 @@ module Mastodon
         end
 
         migrated += batch_size
-        if Time.now - last_time > 1
+        if Time.zone.now - last_time > 1
           status = "Migrated #{migrated} rows"
 
           percentage = 100.0 * migrated / total
           status += " (~#{sprintf('%.2f', percentage)}%, "
 
-          remaining_time = (100.0 - percentage) * (Time.now - started_time) / percentage
+          remaining_time = (100.0 - percentage) * (Time.zone.now - started_time) / percentage
 
           status += "#{(remaining_time / 60).to_i}:"
           status += sprintf('%02d', remaining_time.to_i % 60)
@@ -397,7 +397,7 @@ module Mastodon
           status += ')'
 
           say status, true
-          last_time = Time.now
+          last_time = Time.zone.now
         end
 
         # There are no more rows left to update.
@@ -835,7 +835,7 @@ module Mastodon
       columns(table).find { |column| column.name == name }
     end
 
-    # This will replace the first occurance of a string in a column with
+    # This will replace the first occurrence of a string in a column with
     # the replacement
     # On postgresql we can use `regexp_replace` for that.
     # On mysql we find the location of the pattern, and overwrite it
diff --git a/lib/mastodon/settings_cli.rb b/lib/mastodon/settings_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c81cfbe520148ba0a3e91973555511ed5595577d
--- /dev/null
+++ b/lib/mastodon/settings_cli.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class RegistrationsCLI < Thor
+    def self.exit_on_failure?
+      true
+    end
+
+    desc 'open', 'Open registrations'
+    def open
+      Setting.open_registrations = true
+      say('OK', :green)
+    end
+
+    desc 'close', 'Close registrations'
+    def close
+      Setting.open_registrations = false
+      say('OK', :green)
+    end
+  end
+
+  class SettingsCLI < Thor
+    desc 'registrations SUBCOMMAND ...ARGS', 'Manage state of registrations'
+    subcommand 'registrations', RegistrationsCLI
+  end
+end
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index 04894d34d7e216ea2a66b36568c3f5819d7878cf..abbc31178d2d5770a994720bbd1031eec23cc961 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -9,11 +9,11 @@ module Mastodon
     end
 
     def minor
-      4
+      7
     end
 
     def patch
-      3
+      0
     end
 
     def pre
@@ -32,8 +32,12 @@ module Mastodon
       [to_a.join('.'), flags].join
     end
 
+    def repository
+      'tootsuite/mastodon'
+    end
+
     def source_base_url
-      'https://github.com/tootsuite/mastodon'
+      "https://github.com/#{repository}"
     end
 
     # specify git tag or commit hash here
diff --git a/lib/paperclip/gif_transcoder.rb b/lib/paperclip/gif_transcoder.rb
index 62787983c472afcbee7d3c06ecbc156ae7c46bc1..cbab6fd99a29e7ac7f95a966c0614ee5f27904b9 100644
--- a/lib/paperclip/gif_transcoder.rb
+++ b/lib/paperclip/gif_transcoder.rb
@@ -5,14 +5,7 @@ module Paperclip
   # to convert animated gifs to webm
   class GifTranscoder < Paperclip::Processor
     def make
-      num_frames = identify('-format %n :file', file: file.path).to_i
-
-      unless options[:style] == :original && num_frames > 1
-        tmp_file = Paperclip::TempfileFactory.new.generate(attachment.instance.file_file_name)
-        tmp_file << file.read
-        tmp_file.flush
-        return tmp_file
-      end
+      return File.open(@file.path) unless needs_convert?
 
       final_file = Paperclip::Transcoder.make(file, options, attachment)
 
@@ -22,5 +15,12 @@ module Paperclip
 
       final_file
     end
+
+    private
+
+    def needs_convert?
+      num_frames = identify('-format %n :file', file: file.path).to_i
+      options[:style] == :original && num_frames > 1
+    end
   end
 end
diff --git a/lib/paperclip/lazy_thumbnail.rb b/lib/paperclip/lazy_thumbnail.rb
index aafa213439853bf52826fd24f7141c6a995c4949..542c17fb20efdfab33f4f3402fa38927c39ac634 100644
--- a/lib/paperclip/lazy_thumbnail.rb
+++ b/lib/paperclip/lazy_thumbnail.rb
@@ -5,8 +5,14 @@ module Paperclip
     def make
       return File.open(@file.path) unless needs_convert?
 
-      min_side = [@current_geometry.width, @current_geometry.height].min
-      options[:geometry] = "#{min_side.to_i}x#{min_side.to_i}#" if @target_geometry.square? && min_side < @target_geometry.width
+      if options[:geometry]
+        min_side = [@current_geometry.width, @current_geometry.height].min.to_i
+        options[:geometry] = "#{min_side}x#{min_side}#" if @target_geometry.square? && min_side < @target_geometry.width
+      elsif options[:pixels]
+        width  = Math.sqrt(options[:pixels] * (@current_geometry.width.to_f / @current_geometry.height.to_f)).round.to_i
+        height = Math.sqrt(options[:pixels] * (@current_geometry.height.to_f / @current_geometry.width.to_f)).round.to_i
+        options[:geometry] = "#{width}x#{height}>"
+      end
 
       Paperclip::Thumbnail.make(file, options, attachment)
     end
@@ -14,15 +20,20 @@ module Paperclip
     private
 
     def needs_convert?
-      needs_different_geometry? || needs_different_format?
+      needs_different_geometry? || needs_different_format? || needs_metadata_stripping?
     end
 
     def needs_different_geometry?
-      !@target_geometry.nil? && @current_geometry.width != @target_geometry.width && @current_geometry.height != @target_geometry.height
+      (options[:geometry] && @current_geometry.width != @target_geometry.width && @current_geometry.height != @target_geometry.height) ||
+        (options[:pixels] && @current_geometry.width * @current_geometry.height > options[:pixels])
     end
 
     def needs_different_format?
       @format.present? && @current_format != @format
     end
+
+    def needs_metadata_stripping?
+      @attachment.instance.respond_to?(:local?) && @attachment.instance.local?
+    end
   end
 end
diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake
index 32039c31d1b4b2a6318e7e6fef33879ad49f9327..b76e90131f210ff4227ffca696902b25df012c60 100644
--- a/lib/tasks/db.rake
+++ b/lib/tasks/db.rake
@@ -18,7 +18,7 @@ def each_schema_load_environment
   #    needing to do the same, and we can't even use the same method
   #    to do it.
 
-  if Rails.env == 'development'
+  if Rails.env.development?
     test_conf = ActiveRecord::Base.configurations['test']
 
     if test_conf['database']&.present?
diff --git a/lib/tasks/emojis.rake b/lib/tasks/emojis.rake
index 625a6e55d8bc68f2feb45c707fa83c436a7723c2..892afd89896bf72e0a7da3d575a8c7a75f583217 100644
--- a/lib/tasks/emojis.rake
+++ b/lib/tasks/emojis.rake
@@ -15,7 +15,7 @@ end
 namespace :emojis do
   desc 'Generate a unicode to filename mapping'
   task :generate do
-    source = 'http://www.unicode.org/Public/emoji/5.0/emoji-test.txt'
+    source = 'http://www.unicode.org/Public/emoji/11.0/emoji-test.txt'
     codes  = []
     dest   = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_map.json')
 
@@ -43,6 +43,8 @@ namespace :emojis do
     existence_maps.each do |group|
       existing_one = group.key(true)
 
+      next if existing_one.nil?
+
       group.each_key do |key|
         map[codepoints_to_unicode(key)] = codepoints_to_filename(existing_one)
       end
diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake
index de8c0bb8687ef3c941ce010f7fc5b6241a853dc3..ee9657b0eff06c272091bc7775b8c90e7b9850d2 100644
--- a/lib/tasks/mastodon.rake
+++ b/lib/tasks/mastodon.rake
@@ -1,7 +1,5 @@
 # frozen_string_literal: true
 
-require 'optparse'
-require 'colorize'
 require 'tty-command'
 require 'tty-prompt'
 
@@ -222,7 +220,7 @@ namespace :mastodon do
         end
 
         if prompt.yes?('Do you want to access the uploaded files from your own domain?')
-          env['S3_CLOUDFRONT_HOST'] = prompt.ask('Domain for uploaded files:') do |q|
+          env['S3_ALIAS_HOST'] = prompt.ask('Domain for uploaded files:') do |q|
             q.required true
             q.default "files.#{env['LOCAL_DOMAIN']}"
             q.modify :strip
@@ -280,14 +278,14 @@ namespace :mastodon do
 
         begin
           ActionMailer::Base.smtp_settings = {
-            :port                 => env['SMTP_PORT'],
-            :address              => env['SMTP_SERVER'],
-            :user_name            => env['SMTP_LOGIN'].presence,
-            :password             => env['SMTP_PASSWORD'].presence,
-            :domain               => env['LOCAL_DOMAIN'],
-            :authentication       => env['SMTP_AUTH_METHOD'] == 'none' ? nil : env['SMTP_AUTH_METHOD'] || :plain,
-            :openssl_verify_mode  => env['SMTP_OPENSSL_VERIFY_MODE'],
-            :enable_starttls_auto => true,
+            port:                 env['SMTP_PORT'],
+            address:              env['SMTP_SERVER'],
+            user_name:            env['SMTP_LOGIN'].presence,
+            password:             env['SMTP_PASSWORD'].presence,
+            domain:               env['LOCAL_DOMAIN'],
+            authentication:       env['SMTP_AUTH_METHOD'] == 'none' ? nil : env['SMTP_AUTH_METHOD'] || :plain,
+            openssl_verify_mode:  env['SMTP_OPENSSL_VERIFY_MODE'],
+            enable_starttls_auto: true,
           }
 
           ActionMailer::Base.default_options = {
@@ -326,13 +324,11 @@ namespace :mastodon do
 
         if prompt.yes?('Prepare the database now?')
           prompt.say 'Running `RAILS_ENV=production rails db:setup` ...'
-          prompt.say "\n"
+          prompt.say "\n\n"
 
           if cmd.run!({ RAILS_ENV: 'production', SAFETY_ASSURED: 1 }, :rails, 'db:setup').failure?
-            prompt.say "\n"
             prompt.error 'That failed! Perhaps your configuration is not right'
           else
-            prompt.say "\n"
             prompt.ok 'Done!'
           end
         end
@@ -343,13 +339,11 @@ namespace :mastodon do
 
         if prompt.yes?('Compile the assets now?')
           prompt.say 'Running `RAILS_ENV=production rails assets:precompile` ...'
-          prompt.say "\n"
+          prompt.say "\n\n"
 
           if cmd.run!({ RAILS_ENV: 'production' }, :rails, 'assets:precompile').failure?
-            prompt.say "\n"
             prompt.error 'That failed! Maybe you need swap space?'
           else
-            prompt.say "\n"
             prompt.say 'Done!'
           end
         end
@@ -394,213 +388,6 @@ namespace :mastodon do
     end
   end
 
-  desc 'Execute daily tasks (deprecated)'
-  task :daily do
-    # No-op
-    # All of these tasks are now executed via sidekiq-scheduler
-  end
-
-  desc 'Turn a user into an admin, identified by the USERNAME environment variable'
-  task make_admin: :environment do
-    include RoutingHelper
-
-    account_username = ENV.fetch('USERNAME')
-    user             = User.joins(:account).where(accounts: { username: account_username })
-
-    if user.present?
-      user.update(admin: true)
-      puts "Congrats! #{account_username} is now an admin. \\o/\nNavigate to #{edit_admin_settings_url} to get started"
-    else
-      puts "User could not be found; please make sure an account with the `#{account_username}` username exists."
-    end
-  end
-
-  desc 'Turn a user into a moderator, identified by the USERNAME environment variable'
-  task make_mod: :environment do
-    account_username = ENV.fetch('USERNAME')
-    user             = User.joins(:account).where(accounts: { username: account_username })
-
-    if user.present?
-      user.update(moderator: true)
-      puts "Congrats! #{account_username} is now a moderator \\o/"
-    else
-      puts "User could not be found; please make sure an account with the `#{account_username}` username exists."
-    end
-  end
-
-  desc 'Remove admin and moderator privileges from user identified by the USERNAME environment variable'
-  task revoke_staff: :environment do
-    account_username = ENV.fetch('USERNAME')
-    user             = User.joins(:account).where(accounts: { username: account_username })
-
-    if user.present?
-      user.update(moderator: false, admin: false)
-      puts "#{account_username} is no longer admin or moderator."
-    else
-      puts "User could not be found; please make sure an account with the `#{account_username}` username exists."
-    end
-  end
-
-  desc 'Manually confirms a user with associated user email address stored in USER_EMAIL environment variable.'
-  task confirm_email: :environment do
-    email = ENV.fetch('USER_EMAIL')
-    user  = User.find_by(email: email)
-
-    if user
-      user.update(confirmed_at: Time.now.utc)
-      puts "#{email} confirmed"
-    else
-      abort "#{email} not found"
-    end
-  end
-
-  desc 'Add a user by providing their email, username and initial password.' \
-       'The user will receive a confirmation email, then they must reset their password before logging in.'
-  task add_user: :environment do
-    disable_log_stdout!
-
-    prompt = TTY::Prompt.new
-
-    begin
-      email = prompt.ask('E-mail:', required: true) do |q|
-        q.modify :strip
-      end
-
-      username = prompt.ask('Username:', required: true) do |q|
-        q.modify :strip
-      end
-
-      role = prompt.select('Role:', %w(user moderator admin))
-
-      if prompt.yes?('Proceed to create the user?')
-        user = User.new(email: email, password: SecureRandom.hex, admin: role == 'admin', moderator: role == 'moderator', account_attributes: { username: username })
-
-        if user.save
-          prompt.ok 'User created and confirmation mail sent to the user\'s email address.'
-          prompt.ok "Here is the random password generated for the user: #{user.password}"
-        else
-          prompt.warn 'User was not created because of the following errors:'
-
-          user.errors.each do |key, val|
-            prompt.error "#{key}: #{val}"
-          end
-        end
-      else
-        prompt.ok 'Aborting. Bye!'
-      end
-    rescue TTY::Reader::InputInterrupt
-      prompt.ok 'Aborting. Bye!'
-    end
-  end
-
-  namespace :media do
-    desc 'Removes media attachments that have not been assigned to any status for longer than a day (deprecated)'
-    task clear: :environment do
-      # No-op
-      # This task is now executed via sidekiq-scheduler
-    end
-
-    desc 'Remove media attachments attributed to silenced accounts'
-    task remove_silenced: :environment do
-      MediaAttachment.where(account: Account.silenced).select(:id).find_in_batches do |media_attachments|
-        Maintenance::DestroyMediaWorker.push_bulk(media_attachments.map(&:id))
-      end
-    end
-
-    desc 'Remove cached remote media attachments that are older than NUM_DAYS. By default 7 (week)'
-    task remove_remote: :environment do
-      time_ago = ENV.fetch('NUM_DAYS') { 7 }.to_i.days.ago
-
-      MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).select(:id).find_in_batches do |media_attachments|
-        Maintenance::UncacheMediaWorker.push_bulk(media_attachments.map(&:id))
-      end
-    end
-
-    desc 'Set unknown attachment type for remote-only attachments'
-    task set_unknown: :environment do
-      puts 'Setting unknown attachment type for remote-only attachments...'
-      MediaAttachment.where(file_file_name: nil).where.not(type: :unknown).in_batches.update_all(type: :unknown)
-      puts 'Done!'
-    end
-
-    desc 'Redownload avatars/headers of remote users. Optionally limit to a particular domain with DOMAIN'
-    task redownload_avatars: :environment do
-      accounts = Account.remote
-      accounts = accounts.where(domain: ENV['DOMAIN']) if ENV['DOMAIN'].present?
-
-      accounts.select(:id).find_in_batches do |accounts_batch|
-        Maintenance::RedownloadAccountMediaWorker.push_bulk(accounts_batch.map(&:id))
-      end
-    end
-  end
-
-  namespace :push do
-    desc 'Unsubscribes from PuSH updates of feeds nobody follows locally'
-    task clear: :environment do
-      Pubsubhubbub::UnsubscribeWorker.push_bulk(Account.remote.without_followers.where.not(subscription_expires_at: nil).pluck(:id))
-    end
-
-    desc 'Re-subscribes to soon expiring PuSH subscriptions (deprecated)'
-    task refresh: :environment do
-      # No-op
-      # This task is now executed via sidekiq-scheduler
-    end
-  end
-
-  namespace :feeds do
-    desc 'Clear timelines of inactive users (deprecated)'
-    task clear: :environment do
-      # No-op
-      # This task is now executed via sidekiq-scheduler
-    end
-
-    desc 'Clear all timelines without regenerating them'
-    task clear_all: :environment do
-      Redis.current.keys('feed:*').each { |key| Redis.current.del(key) }
-    end
-
-    desc 'Generates home timelines for users who logged in in the past two weeks'
-    task build: :environment do
-      User.active.select(:id, :account_id).find_in_batches do |users|
-        RegenerationWorker.push_bulk(users.map(&:account_id))
-      end
-    end
-  end
-
-  namespace :emails do
-    desc 'Send out digest e-mails (deprecated)'
-    task digest: :environment do
-      # No-op
-      # This task is now executed via sidekiq-scheduler
-    end
-  end
-
-  namespace :users do
-    desc 'Clear out unconfirmed users (deprecated)'
-    task clear: :environment do
-      # No-op
-      # This task is now executed via sidekiq-scheduler
-    end
-
-    desc 'List e-mails of all admin users'
-    task admins: :environment do
-      puts 'Admin user emails:'
-      puts User.admins.map(&:email).join("\n")
-    end
-  end
-
-  namespace :settings do
-    desc 'Open registrations on this instance'
-    task open_registrations: :environment do
-      Setting.open_registrations = true
-    end
-
-    desc 'Close registrations on this instance'
-    task close_registrations: :environment do
-      Setting.open_registrations = false
-    end
-  end
-
   namespace :webpush do
     desc 'Generate VAPID key'
     task generate_vapid_key: :environment do
@@ -609,221 +396,6 @@ namespace :mastodon do
       puts "VAPID_PUBLIC_KEY=#{vapid_key.public_key}"
     end
   end
-
-  namespace :maintenance do
-    desc 'Update counter caches'
-    task update_counter_caches: :environment do
-      puts 'Updating counter caches for accounts...'
-
-      Account.unscoped.where.not(protocol: :activitypub).select('id').find_in_batches do |batch|
-        Account.where(id: batch.map(&:id)).update_all('statuses_count = (select count(*) from statuses where account_id = accounts.id), followers_count = (select count(*) from follows where target_account_id = accounts.id), following_count = (select count(*) from follows where account_id = accounts.id)')
-      end
-
-      puts 'Updating counter caches for statuses...'
-
-      Status.unscoped.select('id').find_in_batches do |batch|
-        Status.where(id: batch.map(&:id)).update_all('favourites_count = (select count(*) from favourites where favourites.status_id = statuses.id), reblogs_count = (select count(*) from statuses as reblogs where reblogs.reblog_of_id = statuses.id)')
-      end
-
-      puts 'Done!'
-    end
-
-    desc 'Generate static versions of GIF avatars/headers'
-    task add_static_avatars: :environment do
-      puts 'Generating static avatars/headers for GIF ones...'
-
-      Account.unscoped.where(avatar_content_type: 'image/gif').or(Account.unscoped.where(header_content_type: 'image/gif')).find_each do |account|
-        begin
-          account.avatar.reprocess! if account.avatar_content_type == 'image/gif' && !account.avatar.exists?(:static)
-          account.header.reprocess! if account.header_content_type == 'image/gif' && !account.header.exists?(:static)
-        rescue StandardError => e
-          Rails.logger.error "Error while generating static avatars/headers for account #{account.id}: #{e}"
-          next
-        end
-      end
-
-      puts 'Done!'
-    end
-
-    desc 'Ensure referencial integrity'
-    task prepare_for_foreign_keys: :environment do
-      # All the deletes:
-      ActiveRecord::Base.connection.execute('DELETE FROM statuses USING statuses s LEFT JOIN accounts a ON a.id = s.account_id WHERE statuses.id = s.id AND a.id IS NULL')
-
-      if ActiveRecord::Base.connection.table_exists? :account_domain_blocks
-        ActiveRecord::Base.connection.execute('DELETE FROM account_domain_blocks USING account_domain_blocks adb LEFT JOIN accounts a ON a.id = adb.account_id WHERE account_domain_blocks.id = adb.id AND a.id IS NULL')
-      end
-
-      if ActiveRecord::Base.connection.table_exists? :conversation_mutes
-        ActiveRecord::Base.connection.execute('DELETE FROM conversation_mutes USING conversation_mutes cm LEFT JOIN accounts a ON a.id = cm.account_id WHERE conversation_mutes.id = cm.id AND a.id IS NULL')
-        ActiveRecord::Base.connection.execute('DELETE FROM conversation_mutes USING conversation_mutes cm LEFT JOIN conversations c ON c.id = cm.conversation_id WHERE conversation_mutes.id = cm.id AND c.id IS NULL')
-      end
-
-      ActiveRecord::Base.connection.execute('DELETE FROM favourites USING favourites f LEFT JOIN accounts a ON a.id = f.account_id WHERE favourites.id = f.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM favourites USING favourites f LEFT JOIN statuses s ON s.id = f.status_id WHERE favourites.id = f.id AND s.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM blocks USING blocks b LEFT JOIN accounts a ON a.id = b.account_id WHERE blocks.id = b.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM blocks USING blocks b LEFT JOIN accounts a ON a.id = b.target_account_id WHERE blocks.id = b.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM follow_requests USING follow_requests fr LEFT JOIN accounts a ON a.id = fr.account_id WHERE follow_requests.id = fr.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM follow_requests USING follow_requests fr LEFT JOIN accounts a ON a.id = fr.target_account_id WHERE follow_requests.id = fr.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM follows USING follows f LEFT JOIN accounts a ON a.id = f.account_id WHERE follows.id = f.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM follows USING follows f LEFT JOIN accounts a ON a.id = f.target_account_id WHERE follows.id = f.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM mutes USING mutes m LEFT JOIN accounts a ON a.id = m.account_id WHERE mutes.id = m.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM mutes USING mutes m LEFT JOIN accounts a ON a.id = m.target_account_id WHERE mutes.id = m.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM imports USING imports i LEFT JOIN accounts a ON a.id = i.account_id WHERE imports.id = i.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM mentions USING mentions m LEFT JOIN accounts a ON a.id = m.account_id WHERE mentions.id = m.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM mentions USING mentions m LEFT JOIN statuses s ON s.id = m.status_id WHERE mentions.id = m.id AND s.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM notifications USING notifications n LEFT JOIN accounts a ON a.id = n.account_id WHERE notifications.id = n.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM notifications USING notifications n LEFT JOIN accounts a ON a.id = n.from_account_id WHERE notifications.id = n.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM preview_cards USING preview_cards pc LEFT JOIN statuses s ON s.id = pc.status_id WHERE preview_cards.id = pc.id AND s.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM reports USING reports r LEFT JOIN accounts a ON a.id = r.account_id WHERE reports.id = r.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM reports USING reports r LEFT JOIN accounts a ON a.id = r.target_account_id WHERE reports.id = r.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM statuses_tags USING statuses_tags st LEFT JOIN statuses s ON s.id = st.status_id WHERE statuses_tags.tag_id = st.tag_id AND statuses_tags.status_id = st.status_id AND s.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM statuses_tags USING statuses_tags st LEFT JOIN tags t ON t.id = st.tag_id WHERE statuses_tags.tag_id = st.tag_id AND statuses_tags.status_id = st.status_id AND t.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM stream_entries USING stream_entries se LEFT JOIN accounts a ON a.id = se.account_id WHERE stream_entries.id = se.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM subscriptions USING subscriptions s LEFT JOIN accounts a ON a.id = s.account_id WHERE subscriptions.id = s.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM users USING users u LEFT JOIN accounts a ON a.id = u.account_id WHERE users.id = u.id AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM web_settings USING web_settings ws LEFT JOIN users u ON u.id = ws.user_id WHERE web_settings.id = ws.id AND u.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM oauth_access_grants USING oauth_access_grants oag LEFT JOIN users u ON u.id = oag.resource_owner_id WHERE oauth_access_grants.id = oag.id AND oag.resource_owner_id IS NOT NULL AND u.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM oauth_access_grants USING oauth_access_grants oag LEFT JOIN oauth_applications a ON a.id = oag.application_id WHERE oauth_access_grants.id = oag.id AND oag.application_id IS NOT NULL AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM oauth_access_tokens USING oauth_access_tokens oat LEFT JOIN users u ON u.id = oat.resource_owner_id WHERE oauth_access_tokens.id = oat.id AND oat.resource_owner_id IS NOT NULL AND u.id IS NULL')
-      ActiveRecord::Base.connection.execute('DELETE FROM oauth_access_tokens USING oauth_access_tokens oat LEFT JOIN oauth_applications a ON a.id = oat.application_id WHERE oauth_access_tokens.id = oat.id AND oat.application_id IS NOT NULL AND a.id IS NULL')
-
-      # All the nullifies:
-      ActiveRecord::Base.connection.execute('UPDATE statuses SET in_reply_to_id = NULL FROM statuses s LEFT JOIN statuses rs ON rs.id = s.in_reply_to_id WHERE statuses.id = s.id AND s.in_reply_to_id IS NOT NULL AND rs.id IS NULL')
-      ActiveRecord::Base.connection.execute('UPDATE statuses SET in_reply_to_account_id = NULL FROM statuses s LEFT JOIN accounts a ON a.id = s.in_reply_to_account_id WHERE statuses.id = s.id AND s.in_reply_to_account_id IS NOT NULL AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('UPDATE media_attachments SET status_id = NULL FROM media_attachments ma LEFT JOIN statuses s ON s.id = ma.status_id WHERE media_attachments.id = ma.id AND ma.status_id IS NOT NULL AND s.id IS NULL')
-      ActiveRecord::Base.connection.execute('UPDATE media_attachments SET account_id = NULL FROM media_attachments ma LEFT JOIN accounts a ON a.id = ma.account_id WHERE media_attachments.id = ma.id AND ma.account_id IS NOT NULL AND a.id IS NULL')
-      ActiveRecord::Base.connection.execute('UPDATE reports SET action_taken_by_account_id = NULL FROM reports r LEFT JOIN accounts a ON a.id = r.action_taken_by_account_id WHERE reports.id = r.id AND r.action_taken_by_account_id IS NOT NULL AND a.id IS NULL')
-    end
-
-    desc 'Remove deprecated preview cards'
-    task remove_deprecated_preview_cards: :environment do
-      next unless ActiveRecord::Base.connection.table_exists? 'deprecated_preview_cards'
-
-      class DeprecatedPreviewCard < ActiveRecord::Base
-        self.inheritance_column = false
-
-        path = '/preview_cards/:attachment/:id_partition/:style/:filename'
-        if ENV['S3_ENABLED'] != 'true'
-          path = (ENV['PAPERCLIP_ROOT_PATH'] || ':rails_root/public/system') + path
-        end
-
-        has_attached_file :image, styles: { original: '280x120>' }, convert_options: { all: '-quality 80 -strip' }, path: path
-      end
-
-      puts 'Delete records and associated files from deprecated preview cards? [y/N]: '
-      confirm = STDIN.gets.chomp
-
-      if confirm.casecmp('y').zero?
-        DeprecatedPreviewCard.in_batches.destroy_all
-
-        puts 'Drop deprecated preview cards table? [y/N]: '
-        confirm = STDIN.gets.chomp
-
-        if confirm.casecmp('y').zero?
-          ActiveRecord::Migration.drop_table :deprecated_preview_cards
-        end
-      end
-    end
-
-    desc 'Migrate photo preview cards made before 2.1'
-    task migrate_photo_preview_cards: :environment do
-      status_ids = Status.joins(:preview_cards)
-                         .where(preview_cards: { embed_url: '', type: :photo })
-                         .reorder(nil)
-                         .group(:id)
-                         .pluck(:id)
-
-      PreviewCard.where(embed_url: '', type: :photo).delete_all
-      LinkCrawlWorker.push_bulk status_ids
-    end
-
-    desc 'Find case-insensitive username duplicates of local users'
-    task find_duplicate_usernames: :environment do
-      include RoutingHelper
-
-      disable_log_stdout!
-
-      duplicate_masters = Account.find_by_sql('SELECT * FROM accounts WHERE id IN (SELECT min(id) FROM accounts WHERE domain IS NULL GROUP BY lower(username) HAVING count(*) > 1)')
-      pastel = Pastel.new
-
-      duplicate_masters.each do |account|
-        puts pastel.yellow("First of their name: ") + pastel.bold(account.username) + " (#{admin_account_url(account.id)})"
-
-        Account.where('lower(username) = ?', account.username.downcase).where.not(id: account.id).each do |duplicate|
-          puts "  " + pastel.red("Duplicate: ") + admin_account_url(duplicate.id)
-        end
-      end
-    end
-
-    desc 'Remove all home feed regeneration markers'
-    task remove_regeneration_markers: :environment do
-      keys = Redis.current.keys('account:*:regeneration')
-
-      Redis.current.pipelined do
-        keys.each { |key| Redis.current.del(key) }
-      end
-    end
-
-    desc 'Check every known remote account and delete those that no longer exist in origin'
-    task purge_removed_accounts: :environment do
-      prepare_for_options!
-
-      options = {}
-
-      OptionParser.new do |opts|
-        opts.banner = 'Usage: rails mastodon:maintenance:purge_removed_accounts [options]'
-
-        opts.on('-f', '--force', 'Remove all encountered accounts without asking for confirmation') do
-          options[:force] = true
-        end
-
-        opts.on('-h', '--help', 'Display this message') do
-          puts opts
-          exit
-        end
-      end.parse!
-
-      disable_log_stdout!
-
-      total        = Account.remote.where(protocol: :activitypub).count
-      progress_bar = ProgressBar.create(total: total, format: '%c/%C |%w>%i| %e')
-
-      Account.remote.where(protocol: :activitypub).partitioned.find_each do |account|
-        progress_bar.increment
-
-        begin
-          code = Request.new(:head, account.uri).perform(&:code)
-        rescue StandardError
-          # This could happen due to network timeout, DNS timeout, wrong SSL cert, etc,
-          # which should probably not lead to perceiving the account as deleted, so
-          # just skip till next time
-          next
-        end
-
-        if [404, 410].include?(code)
-          if options[:force]
-            SuspendAccountService.new.call(account)
-            account.destroy
-          else
-            progress_bar.pause
-            progress_bar.clear
-            print "\nIt seems like #{account.acct} no longer exists. Purge the account from the database? [Y/n]: ".colorize(:yellow)
-            confirm = STDIN.gets.chomp
-            puts ''
-            progress_bar.resume
-
-            if confirm.casecmp('n').zero?
-              next
-            else
-              SuspendAccountService.new.call(account)
-              account.destroy
-            end
-          end
-        end
-      end
-    end
-  end
 end
 
 def disable_log_stdout!
@@ -834,7 +406,3 @@ def disable_log_stdout!
   HttpLog.configuration.logger = dev_null
   Paperclip.options[:log]      = false
 end
-
-def prepare_for_options!
-  2.times { ARGV.shift }
-end
diff --git a/lib/tasks/repo.rake b/lib/tasks/repo.rake
new file mode 100644
index 0000000000000000000000000000000000000000..8ceec3085461f3e556e10c829942f383968c17fc
--- /dev/null
+++ b/lib/tasks/repo.rake
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+namespace :repo do
+  desc 'Generate the AUTHORS.md file'
+  task :authors do
+    file = File.open(Rails.root.join('AUTHORS.md'), 'w')
+    file << <<~HEADER
+      Authors
+      =======
+
+      Mastodon is available on [GitHub](https://github.com/tootsuite/mastodon)
+      and provided thanks to the work of the following contributors:
+
+    HEADER
+
+    url = 'https://api.github.com/repos/tootsuite/mastodon/contributors?anon=1'
+    HttpLog.config.compact_log = true
+    while url.present?
+      response = HTTP.get(url)
+      contributors = Oj.load(response.body)
+      contributors.each do |c|
+        file << "* [#{c['login']}](#{c['html_url']})\n" if c['login']
+        file << "* [#{c['name']}](mailto:#{c['email']})\n" if c['name']
+      end
+      url = LinkHeader.parse(response.headers['Link']).find_link(%w(rel next))&.href
+    end
+
+    file << <<~FOOTER
+
+      This document is provided for informational purposes only. Since it is only updated once per release, the version you are looking at may be currently out of date. To see the full list of contributors, consider looking at the [git history](https://github.com/tootsuite/mastodon/graphs/contributors) instead.
+    FOOTER
+  end
+
+  desc 'Replace pull requests with authors in the CHANGELOG.md file'
+  task :changelog do
+    path = Rails.root.join('CHANGELOG.md')
+    tmp  = Tempfile.new
+
+    HttpLog.config.compact_log = true
+
+    begin
+      File.open(path, 'r') do |file|
+        file.each_line do |line|
+          if line.start_with?('-')
+            new_line = line.gsub(/#([[:digit:]]+)*/) do |pull_request_reference|
+              pull_request_number = pull_request_reference[1..-1]
+              response = nil
+
+              loop do
+                response = HTTP.headers('Authorization' => "token #{ENV['GITHUB_API_TOKEN']}").get("https://api.github.com/repos/tootsuite/mastodon/pulls/#{pull_request_number}")
+
+                if response.code == 403
+                  sleep_for = (response.headers['X-RateLimit-Reset'].to_i - Time.now.to_i).abs
+                  puts "Sleeping for #{sleep_for} seconds to get over rate limit"
+                  sleep sleep_for
+                else
+                  break
+                end
+              end
+
+              pull_request = Oj.load(response.to_s)
+              "[#{pull_request['user']['login']}](#{pull_request['html_url']})"
+            end
+
+            tmp.puts new_line
+          else
+            tmp.puts line
+          end
+        end
+      end
+
+      tmp.close
+      FileUtils.mv(tmp.path, path)
+    ensure
+      tmp.close
+      tmp.unlink
+    end
+  end
+end
diff --git a/lib/templates/rails/post_deployment_migration/migration.rb b/lib/templates/rails/post_deployment_migration/migration.rb
new file mode 100644
index 0000000000000000000000000000000000000000..503205b84158fa4cfdb7c4b9e2c1262b1c3bb11c
--- /dev/null
+++ b/lib/templates/rails/post_deployment_migration/migration.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class <%= migration_class_name %> < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def change
+  end
+end
diff --git a/nanobox/nginx-local.conf b/nanobox/nginx-local.conf
index f56339cac9b5faea16cc287fd8e355e05ea34b20..c0e883603d2b0026ffb4e3b1b13226ac50786c75 100644
--- a/nanobox/nginx-local.conf
+++ b/nanobox/nginx-local.conf
@@ -38,7 +38,7 @@ http {
 
         root /app/public;
 
-        client_max_body_size 8M;
+        client_max_body_size 80M;
 
         location / {
             try_files $uri @rails;
diff --git a/nanobox/nginx-stream.conf.erb b/nanobox/nginx-stream.conf.erb
index 2a047dd9f6dd5180df0f60cbeb751db0da18780e..12bcc8ca53ab5ba63074e797790753505af797bb 100644
--- a/nanobox/nginx-stream.conf.erb
+++ b/nanobox/nginx-stream.conf.erb
@@ -32,7 +32,7 @@ http {
         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";
+        # 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";
 
         root /app/public;
 
diff --git a/nanobox/nginx-web.conf.erb b/nanobox/nginx-web.conf.erb
index 797201eabf83561cc405f1cd4dedc8174ce2fd07..d96f1bfc7a740cfe90b60bb769b24e4f1eeb9968 100644
--- a/nanobox/nginx-web.conf.erb
+++ b/nanobox/nginx-web.conf.erb
@@ -32,11 +32,11 @@ http {
         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";
+        # 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";
 
         root /app/public;
 
-        client_max_body_size 8M;
+        client_max_body_size 80M;
 
         location / {
             try_files $uri @rails;
diff --git a/package.json b/package.json
index 5b39f015ea22c21f34f9dcab81c07323bca3f61b..5fa6fa8b7641700ae299f0b2ace36c3f4352dfad 100644
--- a/package.json
+++ b/package.json
@@ -2,146 +2,158 @@
   "name": "mastodon",
   "license": "AGPL-3.0-or-later",
   "engines": {
-    "node": ">=6"
+    "node": ">=8 <11"
   },
   "scripts": {
     "postversion": "git push --tags",
-    "build:development": "cross-env RAILS_ENV=development ./bin/webpack",
-    "build:production": "cross-env RAILS_ENV=production ./bin/webpack",
+    "build:development": "cross-env RAILS_ENV=development NODE_ENV=development ./bin/webpack",
+    "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-run-all test:lint test:jest",
-    "test:lint": "eslint -c .eslintrc.yml --ext=js app/javascript/ config/webpack/ streaming/",
+    "test": "${npm_execpath} run test:lint && ${npm_execpath} run test:jest",
+    "test:lint": "eslint --ext=js .",
     "test:jest": "cross-env NODE_ENV=test jest --coverage"
   },
   "repository": {
     "type": "git",
     "url": "https://github.com/tootsuite/mastodon.git"
   },
+  "browserslist": [
+    "last 2 versions",
+    "IE >= 11",
+    "iOS >= 9",
+    "not dead"
+  ],
   "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/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/preset-react": "^7.0.0",
+    "@babel/runtime": "^7.2.0",
+    "@gfx/zopfli": "^1.0.10",
     "array-includes": "^3.0.3",
-    "autoprefixer": "^7.1.6",
-    "axios": "~0.16.2",
-    "babel-core": "^6.25.0",
-    "babel-loader": "^7.1.1",
-    "babel-plugin-lodash": "^3.3.2",
-    "babel-plugin-preval": "^1.6.1",
-    "babel-plugin-react-intl": "^2.3.1",
-    "babel-plugin-syntax-dynamic-import": "^6.18.0",
-    "babel-plugin-transform-class-properties": "^6.24.1",
-    "babel-plugin-transform-decorators-legacy": "^1.3.4",
-    "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
-    "babel-plugin-transform-object-rest-spread": "^6.23.0",
-    "babel-plugin-transform-react-inline-elements": "^6.22.0",
-    "babel-plugin-transform-react-jsx-self": "^6.22.0",
-    "babel-plugin-transform-react-jsx-source": "^6.22.0",
-    "babel-plugin-transform-react-remove-prop-types": "^0.4.10",
-    "babel-plugin-transform-runtime": "^6.23.0",
-    "babel-preset-env": "^1.6.1",
-    "babel-preset-react": "^6.24.1",
+    "autoprefixer": "^9.4.3",
+    "axios": "^0.18.0",
+    "babel-core": "^7.0.0-bridge.0",
+    "babel-loader": "^8.0.4",
+    "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-runtime": "^6.26.0",
     "classnames": "^2.2.5",
-    "compression-webpack-plugin": "^1.0.1",
-    "cross-env": "^5.1.1",
-    "css-loader": "^0.28.4",
+    "compression-webpack-plugin": "^2.0.0",
+    "cross-env": "^5.1.4",
+    "css-loader": "^2.1.0",
+    "cssnano": "^4.1.8",
     "detect-passive-events": "^1.0.2",
-    "dotenv": "^4.0.0",
+    "dotenv": "^6.2.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.2",
-    "extract-text-webpack-plugin": "^3.0.2",
-    "file-loader": "^0.11.2",
+    "express": "^4.16.4",
+    "fibers": "^3.1.1",
+    "file-loader": "^3.0.1",
     "font-awesome": "^4.7.0",
     "glob": "^7.1.1",
-    "http-link-header": "^0.8.0",
+    "history": "^4.7.2",
+    "http-link-header": "^1.0.2",
     "immutable": "^3.8.2",
     "imports-loader": "^0.8.0",
-    "intersection-observer": "^0.5.0",
+    "intersection-observer": "^0.5.1",
     "intl": "^1.2.5",
     "intl-messageformat": "^2.2.0",
     "intl-relativeformat": "^2.1.0",
     "is-nan": "^1.2.1",
-    "js-yaml": "^3.9.0",
-    "lodash": "^4.17.4",
+    "js-yaml": "^3.11.0",
+    "lodash": "^4.7.11",
     "mark-loader": "^0.1.6",
-    "marky": "^1.2.0",
+    "marky": "^1.2.1",
+    "mini-css-extract-plugin": "^0.5.0",
     "mkdirp": "^0.5.1",
-    "node-sass": "^4.7.2",
-    "npm-run-all": "^4.1.2",
     "npmlog": "^4.1.2",
     "object-assign": "^4.1.1",
     "object-fit-images": "^3.2.3",
     "object.values": "^1.0.4",
-    "offline-plugin": "^4.8.3",
-    "path-complete-extname": "^0.1.0",
+    "offline-plugin": "^5.0.6",
+    "path-complete-extname": "^1.0.0",
     "pg": "^6.4.0",
-    "postcss-loader": "^2.0.9",
+    "postcss-loader": "^3.0.0",
     "postcss-object-fit-images": "^1.1.2",
-    "postcss-smart-import": "^0.7.5",
-    "precss": "^2.0.0",
     "prop-types": "^15.5.10",
     "punycode": "^2.1.0",
-    "rails-ujs": "^5.1.2",
-    "react": "^16.3.0",
-    "react-dom": "^16.3.0",
-    "react-hotkeys": "^0.10.0",
+    "rails-ujs": "^5.2.2",
+    "react": "^16.7.0",
+    "react-dom": "^16.7.0",
+    "react-hotkeys": "^1.1.4",
     "react-immutable-proptypes": "^2.1.0",
     "react-immutable-pure-component": "^1.1.1",
-    "react-intl": "^2.4.0",
+    "react-intl": "^2.7.2",
+    "react-masonry-infinite": "^1.2.2",
     "react-motion": "^0.5.2",
-    "react-notification": "^6.8.2",
+    "react-notification": "^6.8.4",
     "react-overlays": "^0.8.3",
-    "react-redux": "^5.0.4",
-    "react-redux-loading-bar": "^2.9.3",
+    "react-redux": "^6.0.0",
+    "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-sparklines": "^1.7.0",
-    "react-swipeable-views": "^0.12.3",
-    "react-textarea-autosize": "^5.2.1",
+    "react-swipeable-views": "^0.13.0",
+    "react-textarea-autosize": "^7.1.0",
     "react-toggle": "^4.0.1",
     "redis": "^2.7.1",
-    "redux": "^3.7.1",
+    "redux": "^4.0.1",
     "redux-immutable": "^4.0.0",
     "redux-thunk": "^2.2.0",
+    "rellax": "^1.7.1",
     "requestidlecallback": "^0.3.0",
-    "reselect": "^3.0.1",
-    "resolve-url-loader": "^2.2.0",
+    "reselect": "^4.0.0",
     "rimraf": "^2.6.1",
-    "sass-loader": "^6.0.6",
-    "stringz": "^0.3.0",
-    "style-loader": "^0.19.0",
+    "sass": "^1.15.2",
+    "sass-loader": "^7.0.3",
+    "stringz": "^1.0.0",
+    "style-loader": "0.23.1",
     "substring-trie": "^1.0.2",
     "throng": "^4.0.0",
     "tiny-queue": "^0.2.1",
+    "uglifyjs-webpack-plugin": "^2.1.1",
     "uuid": "^3.1.0",
-    "uws": "^8.14.0",
-    "webpack": "^3.9.1",
-    "webpack-bundle-analyzer": "^2.9.1",
-    "webpack-manifest-plugin": "^1.2.1",
-    "webpack-merge": "^4.1.1",
-    "websocket.js": "^0.1.12",
-    "whatwg-url": "^6.4.1"
+    "uws": "10.148.0",
+    "webpack": "^4.28.3",
+    "webpack-assets-manifest": "^3.1.1",
+    "webpack-bundle-analyzer": "^3.0.3",
+    "webpack-cli": "^3.1.2",
+    "webpack-merge": "^4.1.5",
+    "websocket.js": "^0.1.12"
   },
   "devDependencies": {
-    "babel-eslint": "^8.2.3",
-    "enzyme": "^3.2.0",
-    "enzyme-adapter-react-16": "^1.1.0",
-    "eslint": "^4.19.1",
-    "eslint-plugin-import": "^2.8.0",
-    "eslint-plugin-jsx-a11y": "^6.0.3",
-    "eslint-plugin-promise": "^3.8.0",
-    "eslint-plugin-react": "^7.8.2",
-    "jest": "^21.2.1",
-    "raf": "^3.4.0",
-    "react-intl-translations-manager": "^5.0.0",
-    "react-test-renderer": "^16.2.0",
-    "webpack-dev-server": "^2.9.5",
+    "babel-eslint": "^10.0.1",
+    "babel-jest": "^23.6.0",
+    "enzyme": "^3.8.0",
+    "enzyme-adapter-react-16": "^1.7.1",
+    "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-react": "~7.12.1",
+    "jest": "^23.6.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": "*",
-    "node-zopfli": "^2.0.2"
+    "fsevents": "*"
   }
 }
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..1c820c3181b19f05ce82f4178b78950fea2212f9
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,7 @@
+module.exports = ({ env }) => ({
+  plugins: {
+    autoprefixer: {},
+    'postcss-object-fit-images': {},
+    cssnano: env === 'production' ? {} : false,
+  },
+});
diff --git a/scalingo.json b/scalingo.json
index 873731ac9a38e1bb5ee3884a715dd47f58d082e0..dd8fb5530cfd5494a205e6eae478082faffb5dec 100644
--- a/scalingo.json
+++ b/scalingo.json
@@ -91,6 +91,11 @@
       "description": "Internal scalingo configuration",
       "required": true,
       "value": "https://github.com/Scalingo/multi-buildpack.git"
+    },
+    "WITH_FFPROBE": {
+      "description": "Internal scalingo configuration to install ffprobe",
+      "required": true,
+      "value": "true"
     }
   },
   "scripts": {
diff --git a/spec/controllers/about_controller_spec.rb b/spec/controllers/about_controller_spec.rb
index 2089b3b1623c992eb6e2612da0735be0c3ae899a..03dddd8c13468c4a684cd6d4b734db387ba82639 100644
--- a/spec/controllers/about_controller_spec.rb
+++ b/spec/controllers/about_controller_spec.rb
@@ -8,10 +8,6 @@ RSpec.describe AboutController, type: :controller do
       get :show
     end
 
-    it 'assigns @body_classes' do
-      expect(assigns(:body_classes)).to eq 'about-body'
-    end
-
     it 'assigns @instance_presenter' do
       expect(assigns(:instance_presenter)).to be_kind_of InstancePresenter
     end
@@ -26,10 +22,6 @@ RSpec.describe AboutController, type: :controller do
       get :more
     end
 
-    it 'assigns @body_classes' do
-      expect(assigns(:body_classes)).to eq 'about-body'
-    end
-
     it 'assigns @instance_presenter' do
       expect(assigns(:instance_presenter)).to be_kind_of InstancePresenter
     end
@@ -44,10 +36,6 @@ RSpec.describe AboutController, type: :controller do
       get :terms
     end
 
-    it 'assigns @body_classes' do
-      expect(assigns(:body_classes)).to eq 'about-body'
-    end
-
     it 'returns http success' do
       expect(response).to have_http_status(200)
     end
diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb
index 18c249c07ebdd69b9b2cbe5a10468867cc625c1c..3ba5d8aec2d92bd6cc4b5fdd7b3edae1616e6348 100644
--- a/spec/controllers/accounts_controller_spec.rb
+++ b/spec/controllers/accounts_controller_spec.rb
@@ -3,8 +3,8 @@ require 'rails_helper'
 RSpec.describe AccountsController, type: :controller do
   render_views
 
-  let(:alice)  { Fabricate(:account, username: 'alice') }
-  let(:eve)  { Fabricate(:user) }
+  let(:alice) { Fabricate(:account, username: 'alice') }
+  let(:eve) { Fabricate(:user) }
 
   describe 'GET #show' do
     let!(:status1) { Status.create!(account: alice, text: 'Hello world') }
diff --git a/spec/controllers/activitypub/collections_controller_spec.rb b/spec/controllers/activitypub/collections_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..34114cc85c69954d766c8fa8773c97ba5fed58de
--- /dev/null
+++ b/spec/controllers/activitypub/collections_controller_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe ActivityPub::CollectionsController, type: :controller do
+  describe 'POST #show' do
+    let(:account) { Fabricate(:account) }
+
+    context 'id is "featured"' do
+      it 'returns 200 with "application/activity+json"' do
+        post :show, params: { id: 'featured', account_username: account.username }
+
+        expect(response).to have_http_status(200)
+        expect(response.content_type).to eq 'application/activity+json'
+      end
+    end
+
+    context 'id is not "featured"' do
+      it 'returns 404' do
+        post :show, params: { id: 'hoge', account_username: account.username }
+        expect(response).to have_http_status(404)
+      end
+    end
+  end
+end
diff --git a/spec/controllers/activitypub/inboxes_controller_spec.rb b/spec/controllers/activitypub/inboxes_controller_spec.rb
index 5c12fea7df8457451c4742d62b6231c7f1c28ad4..4055d93424c2682b983632c31e895ab99152ff8d 100644
--- a/spec/controllers/activitypub/inboxes_controller_spec.rb
+++ b/spec/controllers/activitypub/inboxes_controller_spec.rb
@@ -1,7 +1,29 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 
 RSpec.describe ActivityPub::InboxesController, type: :controller do
   describe 'POST #create' do
-    pending
+    context 'if signed_request_account' do
+      it 'returns 202' do
+        allow(controller).to receive(:signed_request_account) do
+          Fabricate(:account)
+        end
+
+        post :create
+        expect(response).to have_http_status(202)
+      end
+    end
+
+    context 'not signed_request_account' do
+      it 'returns 401' do
+        allow(controller).to receive(:signed_request_account) do
+          false
+        end
+
+        post :create
+        expect(response).to have_http_status(401)
+      end
+    end
   end
 end
diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb
index 197e019fed3283beb0e505f6a67ba774c46183f3..a348ab3d75eddd9daf9805bf5372591c4c72a859 100644
--- a/spec/controllers/admin/accounts_controller_spec.rb
+++ b/spec/controllers/admin/accounts_controller_spec.rb
@@ -24,8 +24,8 @@ RSpec.describe Admin::AccountsController, type: :controller do
         expect(h[:local]).to eq '1'
         expect(h[:remote]).to eq '1'
         expect(h[:by_domain]).to eq 'domain'
+        expect(h[:active]).to eq '1'
         expect(h[:silenced]).to eq '1'
-        expect(h[:recent]).to eq '1'
         expect(h[:suspended]).to eq '1'
         expect(h[:username]).to eq 'username'
         expect(h[:display_name]).to eq 'display name'
@@ -39,8 +39,8 @@ RSpec.describe Admin::AccountsController, type: :controller do
         local: '1',
         remote: '1',
         by_domain: 'domain',
+        active: '1',
         silenced: '1',
-        recent: '1',
         suspended: '1',
         username: 'username',
         display_name: 'display name',
@@ -75,7 +75,6 @@ RSpec.describe Admin::AccountsController, type: :controller do
     end
   end
 
-
   describe 'POST #subscribe' do
     subject { post :subscribe, params: { id: account.id } }
 
@@ -192,58 +191,6 @@ RSpec.describe Admin::AccountsController, type: :controller do
     end
   end
 
-  describe 'POST #disable' do
-    subject { post :disable, params: { id: account.id } }
-
-    let(:current_user) { Fabricate(:user, admin: current_user_admin) }
-    let(:account) { Fabricate(:account, user: user) }
-    let(:user) { Fabricate(:user, disabled: false, admin: target_user_admin) }
-
-    context 'when user is admin' do
-      let(:current_user_admin) { true }
-
-      context 'when target user is admin' do
-        let(:target_user_admin) { true }
-
-        it 'fails to disable account' do
-          is_expected.to have_http_status :forbidden
-          expect(user.reload).not_to be_disabled
-        end
-      end
-
-      context 'when target user is not admin' do
-        let(:target_user_admin) { false }
-
-        it 'succeeds in disabling account' do
-          is_expected.to redirect_to admin_account_path(account.id)
-          expect(user.reload).to be_disabled
-        end
-      end
-    end
-
-    context 'when user is not admin' do
-      let(:current_user_admin) { false }
-
-      context 'when target user is admin' do
-        let(:target_user_admin) { true }
-
-        it 'fails to disable account' do
-          is_expected.to have_http_status :forbidden
-          expect(user.reload).not_to be_disabled
-        end
-      end
-
-      context 'when target user is not admin' do
-        let(:target_user_admin) { false }
-
-        it 'fails to disable account' do
-          is_expected.to have_http_status :forbidden
-          expect(user.reload).not_to be_disabled
-        end
-      end
-    end
-  end
-
   describe 'POST #redownload' do
     subject { post :redownload, params: { id: account.id } }
 
diff --git a/spec/controllers/admin/action_logs_controller_spec.rb b/spec/controllers/admin/action_logs_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4720ed2e2bbd3c0d8a4f0bcb0ca9346361d49ef3
--- /dev/null
+++ b/spec/controllers/admin/action_logs_controller_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Admin::ActionLogsController, type: :controller do
+  describe 'GET #index' do
+    it 'returns 200' do
+      sign_in Fabricate(:user, admin: true)
+      get :index, params: { page: 1 }
+
+      expect(response).to have_http_status(200)
+    end
+  end
+end
diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..73b50e721881523b015dbaf668e1ba0eadf5020e
--- /dev/null
+++ b/spec/controllers/admin/dashboard_controller_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Admin::DashboardController, type: :controller do
+  describe 'GET #index' do
+    it 'returns 200' do
+      sign_in Fabricate(:user, admin: true)
+      get :index
+
+      expect(response).to have_http_status(200)
+    end
+  end
+end
diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb
index 79e7fea42369a4896208518cf8777fc896310c19..129bf888370020bc10789f6c5e251dd0a72e377d 100644
--- a/spec/controllers/admin/domain_blocks_controller_spec.rb
+++ b/spec/controllers/admin/domain_blocks_controller_spec.rb
@@ -7,26 +7,6 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
     sign_in Fabricate(:user, admin: true), scope: :user
   end
 
-  describe 'GET #index' do
-    around do |example|
-      default_per_page = DomainBlock.default_per_page
-      DomainBlock.paginates_per 1
-      example.run
-      DomainBlock.paginates_per default_per_page
-    end
-
-    it 'renders domain blocks' do
-      2.times { Fabricate(:domain_block) }
-
-      get :index, params: { page: 2 }
-
-      assigned = assigns(:domain_blocks)
-      expect(assigned.count).to eq 1
-      expect(assigned.klass).to be DomainBlock
-      expect(response).to have_http_status(200)
-    end
-  end
-
   describe 'GET #new' do
     it 'assigns a new domain block' do
       get :new
@@ -53,7 +33,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
 
       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_domain_blocks_path)
+      expect(response).to redirect_to(admin_instances_path(limited: '1'))
     end
 
     it 'renders new when failed to save' do
@@ -76,7 +56,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
 
       expect(service).to have_received(:call).with(domain_block, true)
       expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.destroyed_msg')
-      expect(response).to redirect_to(admin_domain_blocks_path)
+      expect(response).to redirect_to(admin_instances_path(limited: '1'))
     end
   end
 end
diff --git a/spec/controllers/admin/email_domain_blocks_controller_spec.rb b/spec/controllers/admin/email_domain_blocks_controller_spec.rb
index 133d38ff103214baa5f401d4465f9a19b9a54e8f..52db56f4e8d9b4aea282816a9976fbaf3ac539ce 100644
--- a/spec/controllers/admin/email_domain_blocks_controller_spec.rb
+++ b/spec/controllers/admin/email_domain_blocks_controller_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe Admin::EmailDomainBlocksController, type: :controller do
 
   describe 'POST #create' do
     it 'blocks the domain when succeeded to save' do
-      post :create, params: { email_domain_block: { domain: 'example.com'} }
+      post :create, params: { email_domain_block: { domain: 'example.com' } }
 
       expect(flash[:notice]).to eq I18n.t('admin.email_domain_blocks.created_msg')
       expect(response).to redirect_to(admin_email_domain_blocks_path)
@@ -50,7 +50,7 @@ RSpec.describe Admin::EmailDomainBlocksController, type: :controller do
   describe 'DELETE #destroy' do
     it 'unblocks the domain' do
       email_domain_block = Fabricate(:email_domain_block)
-      delete :destroy, params: { id: email_domain_block.id } 
+      delete :destroy, params: { id: email_domain_block.id }
 
       expect(flash[:notice]).to eq I18n.t('admin.email_domain_blocks.destroyed_msg')
       expect(response).to redirect_to(admin_email_domain_blocks_path)
diff --git a/spec/controllers/admin/invites_controller_spec.rb b/spec/controllers/admin/invites_controller_spec.rb
index e7d9954118f41a9c69201b68b8a7a5a018c7cd24..449a699e4038009be106cd46fd32ffb55d78f2a5 100644
--- a/spec/controllers/admin/invites_controller_spec.rb
+++ b/spec/controllers/admin/invites_controller_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 
 describe Admin::InvitesController do
@@ -24,7 +26,7 @@ describe Admin::InvitesController do
     subject { post :create, params: { invite: { max_uses: '10', expires_in: 1800 } } }
 
     it 'succeeds to create a invite' do
-      expect{ subject }.to change { Invite.count }.by(1)
+      expect { subject }.to change { Invite.count }.by(1)
       expect(subject).to redirect_to admin_invites_path
       expect(Invite.last).to have_attributes(user_id: user.id, max_uses: 10)
     end
@@ -40,4 +42,18 @@ describe Admin::InvitesController do
       expect(invite.reload).to be_expired
     end
   end
+
+  describe 'POST #deactivate_all' do
+    it 'expires all invites, then redirects to admin_invites_path' do
+      invites = Fabricate.times(2, :invite, expires_at: nil)
+
+      post :deactivate_all
+
+      invites.each do |invite|
+        expect(invite.reload).to be_expired
+      end
+
+      expect(response).to redirect_to admin_invites_path
+    end
+  end
 end
diff --git a/spec/controllers/admin/report_notes_controller_spec.rb b/spec/controllers/admin/report_notes_controller_spec.rb
index 2c32303fb39194784fa3823e32dda1f9fd87b6d6..ec5872c7d2a360cf54dbd7f88bf548a92d92f209 100644
--- a/spec/controllers/admin/report_notes_controller_spec.rb
+++ b/spec/controllers/admin/report_notes_controller_spec.rb
@@ -15,7 +15,6 @@ describe Admin::ReportNotesController do
     let(:report) { Fabricate(:report, action_taken: action_taken, action_taken_by_account_id: account_id) }
 
     context 'when parameter is valid' do
-
       context 'when report is unsolved' do
         let(:action_taken) { false }
         let(:account_id) { nil }
@@ -24,7 +23,7 @@ describe Admin::ReportNotesController do
           let(:params) { { report_note: { content: 'test content', report_id: report.id }, create_and_resolve: nil } }
 
           it 'creates a report note and resolves report' do
-            expect{ subject }.to change{ ReportNote.count }.by(1)
+            expect { subject }.to change { ReportNote.count }.by(1)
             expect(report.reload).to be_action_taken
             expect(subject).to redirect_to admin_reports_path
           end
@@ -34,7 +33,7 @@ describe Admin::ReportNotesController do
           let(:params) { { report_note: { content: 'test content', report_id: report.id } } }
 
           it 'creates a report note and does not resolve report' do
-            expect{ subject }.to change{ ReportNote.count }.by(1)
+            expect { subject }.to change { ReportNote.count }.by(1)
             expect(report.reload).not_to be_action_taken
             expect(subject).to redirect_to admin_report_path(report)
           end
@@ -49,7 +48,7 @@ describe Admin::ReportNotesController do
           let(:params) { { report_note: { content: 'test content', report_id: report.id }, create_and_unresolve: nil } }
 
           it 'creates a report note and unresolves report' do
-            expect{ subject }.to change{ ReportNote.count }.by(1)
+            expect { subject }.to change { ReportNote.count }.by(1)
             expect(report.reload).not_to be_action_taken
             expect(subject).to redirect_to admin_report_path(report)
           end
@@ -59,7 +58,7 @@ describe Admin::ReportNotesController do
           let(:params) { { report_note: { content: 'test content', report_id: report.id } } }
 
           it 'creates a report note and does not unresolve report' do
-            expect{ subject }.to change{ ReportNote.count }.by(1)
+            expect { subject }.to change { ReportNote.count }.by(1)
             expect(report.reload).to be_action_taken
             expect(subject).to redirect_to admin_report_path(report)
           end
@@ -84,7 +83,7 @@ describe Admin::ReportNotesController do
     let!(:report_note) { Fabricate(:report_note) }
 
     it 'deletes note' do
-      expect{ subject }.to change{ ReportNote.count }.by(-1)
+      expect { subject }.to change { ReportNote.count }.by(-1)
       expect(subject).to redirect_to admin_report_path(report_note.report)
     end
   end
diff --git a/spec/controllers/admin/reported_statuses_controller_spec.rb b/spec/controllers/admin/reported_statuses_controller_spec.rb
index 7adbf36b9c9a80942bc33a79fcbd4908365f1b59..c358506d6dce88b136487dbefd266d00719aec8d 100644
--- a/spec/controllers/admin/reported_statuses_controller_spec.rb
+++ b/spec/controllers/admin/reported_statuses_controller_spec.rb
@@ -13,7 +13,7 @@ describe Admin::ReportedStatusesController do
 
   describe 'POST #create' do
     subject do
-      -> { post :create, params: { :report_id  => report, action => '', :form_status_batch => { status_ids: status_ids } } }
+      -> { post :create, params: { :report_id => report, action => '', :form_status_batch => { status_ids: status_ids } } }
     end
 
     let(:action) { 'nsfw_on' }
diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb
index e50c02a729072e42e2dcdd7f96afd8f65a57cfab..b428299eeb0d38b3497d75b2f7a6d8f306894c95 100644
--- a/spec/controllers/admin/reports_controller_spec.rb
+++ b/spec/controllers/admin/reports_controller_spec.rb
@@ -46,88 +46,37 @@ describe Admin::ReportsController do
     end
   end
 
-  describe 'PUT #update' do
-    describe 'with an unknown outcome' do
-      it 'rejects the change' do
-        report = Fabricate(:report)
-        put :update, params: { id: report, outcome: 'unknown' }
-
-        expect(response).to have_http_status(404)
-      end
-    end
-
-    describe 'with an outcome of `resolve`' do
-      it 'resolves the report' do
-        report = Fabricate(:report)
-
-        put :update, params: { id: report, outcome: 'resolve' }
-        expect(response).to redirect_to(admin_reports_path)
-        report.reload
-        expect(report.action_taken_by_account).to eq user.account
-        expect(report.action_taken).to eq true
-      end
-    end
-
-    describe 'with an outcome of `suspend`' do
-      it 'suspends the reported account' do
-        report = Fabricate(:report)
-        allow(Admin::SuspensionWorker).to receive(:perform_async)
-
-        put :update, params: { id: report, outcome: 'suspend' }
-        expect(response).to redirect_to(admin_reports_path)
-        report.reload
-        expect(report.action_taken_by_account).to eq user.account
-        expect(report.action_taken).to eq true
-        expect(Admin::SuspensionWorker).
-          to have_received(:perform_async).with(report.target_account_id)
-      end
-    end
-
-    describe 'with an outsome of `silence`' do
-      it 'silences the reported account' do
-        report = Fabricate(:report)
-
-        put :update, params: { id: report, outcome: 'silence' }
-        expect(response).to redirect_to(admin_reports_path)
-        report.reload
-        expect(report.action_taken_by_account).to eq user.account
-        expect(report.action_taken).to eq true
-        expect(report.target_account).to be_silenced
-      end
-    end
-
-    describe 'with an outsome of `reopen`' do
-      it 'reopens the report' do
-        report = Fabricate(:report)
+  describe 'POST #reopen' do
+    it 'reopens the report' do
+      report = Fabricate(:report)
 
-        put :update, params: { id: report, outcome: 'reopen' }
-        expect(response).to redirect_to(admin_report_path(report))
-        report.reload
-        expect(report.action_taken_by_account).to eq nil
-        expect(report.action_taken).to eq false
-      end
+      put :reopen, params: { id: report }
+      expect(response).to redirect_to(admin_report_path(report))
+      report.reload
+      expect(report.action_taken_by_account).to eq nil
+      expect(report.action_taken).to eq false
     end
+  end
 
-    describe 'with an outsome of `assign_to_self`' do
-      it 'reopens the report' do
-        report = Fabricate(:report)
+  describe 'POST #assign_to_self' do
+    it 'reopens the report' do
+      report = Fabricate(:report)
 
-        put :update, params: { id: report, outcome: 'assign_to_self' }
-        expect(response).to redirect_to(admin_report_path(report))
-        report.reload
-        expect(report.assigned_account).to eq user.account
-      end
+      put :assign_to_self, params: { id: report }
+      expect(response).to redirect_to(admin_report_path(report))
+      report.reload
+      expect(report.assigned_account).to eq user.account
     end
+  end
 
-    describe 'with an outsome of `unassign`' do
-      it 'reopens the report' do
-        report = Fabricate(:report)
+  describe 'POST #unassign' do
+    it 'reopens the report' do
+      report = Fabricate(:report)
 
-        put :update, params: { id: report, outcome: 'unassign' }
-        expect(response).to redirect_to(admin_report_path(report))
-        report.reload
-        expect(report.assigned_account).to eq nil
-      end
+      put :unassign, params: { id: report }
+      expect(response).to redirect_to(admin_report_path(report))
+      report.reload
+      expect(report.assigned_account).to eq nil
     end
   end
 end
diff --git a/spec/controllers/admin/silences_controller_spec.rb b/spec/controllers/admin/silences_controller_spec.rb
deleted file mode 100644
index 78560eb393a483b5834698dee9141437d5a70d6b..0000000000000000000000000000000000000000
--- a/spec/controllers/admin/silences_controller_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require 'rails_helper'
-
-describe Admin::SilencesController do
-  render_views
-
-  before do
-    sign_in Fabricate(:user, admin: true), scope: :user
-  end
-
-  describe 'POST #create' do
-    it 'redirects to admin accounts page' do
-      account = Fabricate(:account, silenced: false)
-
-      post :create, params: { account_id: account.id }
-
-      account.reload
-      expect(account.silenced?).to eq true
-      expect(response).to redirect_to(admin_accounts_path)
-    end
-  end
-
-  describe 'DELETE #destroy' do
-    it 'redirects to admin accounts page' do
-      account = Fabricate(:account, silenced: true)
-
-      delete :destroy, params: { account_id: account.id }
-
-      account.reload
-      expect(account.silenced?).to eq false
-      expect(response).to redirect_to(admin_accounts_path)
-    end
-  end
-end
diff --git a/spec/controllers/admin/statuses_controller_spec.rb b/spec/controllers/admin/statuses_controller_spec.rb
index 6afcc1442579b008349b45a27416bc0b5e8e8707..1a08c10b7e873fd1c2052419601e999d797acee3 100644
--- a/spec/controllers/admin/statuses_controller_spec.rb
+++ b/spec/controllers/admin/statuses_controller_spec.rb
@@ -24,7 +24,7 @@ describe Admin::StatusesController do
     end
 
     it 'returns http success with media' do
-      get :index, params: { account_id: account.id , media: true }
+      get :index, params: { account_id: account.id, media: true }
 
       statuses = assigns(:statuses).to_a
       expect(statuses.size).to eq 1
diff --git a/spec/controllers/admin/suspensions_controller_spec.rb b/spec/controllers/admin/suspensions_controller_spec.rb
deleted file mode 100644
index ddfc938d1876c10d6d57ad99d1dadc10c8c96253..0000000000000000000000000000000000000000
--- a/spec/controllers/admin/suspensions_controller_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'rails_helper'
-
-describe Admin::SuspensionsController do
-  render_views
-
-  before do
-    sign_in Fabricate(:user, admin: true), scope: :user
-  end
-
-  describe 'POST #create' do
-    it 'redirects to admin accounts page' do
-      account = Fabricate(:account, suspended: false)
-      expect(Admin::SuspensionWorker).to receive(:perform_async).with(account.id)
-
-      post :create, params: { account_id: account.id }
-
-      expect(response).to redirect_to(admin_accounts_path)
-    end
-  end
-
-  describe 'DELETE #destroy' do
-    it 'redirects to admin accounts page' do
-      account = Fabricate(:account, suspended: true)
-
-      delete :destroy, params: { account_id: account.id }
-
-      account.reload
-      expect(account.suspended?).to eq false
-      expect(response).to redirect_to(admin_accounts_path)
-    end
-  end
-end
diff --git a/spec/controllers/admin/tags_controller_spec.rb b/spec/controllers/admin/tags_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3af994071ce724cb09b66fd26f4d601cd1c39679
--- /dev/null
+++ b/spec/controllers/admin/tags_controller_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe Admin::TagsController, type: :controller do
+  render_views
+
+  before do
+    sign_in Fabricate(:user, admin: true)
+  end
+
+  describe 'GET #index' do
+    before do
+      account_tag_stat = Fabricate(:tag).account_tag_stat
+      account_tag_stat.update(hidden: hidden, accounts_count: 1)
+      get :index, params: { hidden: hidden }
+    end
+
+    context 'with hidden tags' do
+      let(:hidden) { true }
+
+      it 'returns status 200' do
+        expect(response).to have_http_status(200)
+      end
+    end
+
+    context 'without hidden tags' do
+      let(:hidden) { false }
+
+      it 'returns status 200' do
+        expect(response).to have_http_status(200)
+      end
+    end
+  end
+
+  describe 'POST #hide' do
+    let(:tag) { Fabricate(:tag) }
+
+    before do
+      tag.account_tag_stat.update(hidden: false)
+      post :hide, params: { id: tag.id }
+    end
+
+    it 'hides tag' do
+      tag.reload
+      expect(tag).to be_hidden
+    end
+
+    it 'redirects to admin_tags_path' do
+      expect(response).to redirect_to(admin_tags_path(controller.instance_variable_get(:@filter_params)))
+    end
+  end
+
+  describe 'POST #unhide' do
+    let(:tag) { Fabricate(:tag) }
+
+    before do
+      tag.account_tag_stat.update(hidden: true)
+      post :unhide, params: { id: tag.id }
+    end
+
+    it 'unhides tag' do
+      tag.reload
+      expect(tag).not_to be_hidden
+    end
+
+    it 'redirects to admin_tags_path' do
+      expect(response).to redirect_to(admin_tags_path(controller.instance_variable_get(:@filter_params)))
+    end
+  end
+end
diff --git a/spec/controllers/api/salmon_controller_spec.rb b/spec/controllers/api/salmon_controller_spec.rb
index 5f01f8073527750072a5937b96dc5848100eedcb..235a29af0041e5207b145b521867789fbd36ed65 100644
--- a/spec/controllers/api/salmon_controller_spec.rb
+++ b/spec/controllers/api/salmon_controller_spec.rb
@@ -15,8 +15,7 @@ RSpec.describe Api::SalmonController, type: :controller do
   describe 'POST #update' do
     context 'with valid post data' do
       before do
-        request.env['RAW_POST_DATA'] = File.read(File.join(Rails.root, 'spec', 'fixtures', 'salmon', 'mention.xml'))
-        post :update, params: { id: account.id }
+        post :update, params: { id: account.id }, body: File.read(Rails.root.join('spec', 'fixtures', 'salmon', 'mention.xml'))
       end
 
       it 'contains XML in the request body' do
@@ -42,8 +41,7 @@ RSpec.describe Api::SalmonController, type: :controller do
 
     context 'with empty post data' do
       before do
-        request.env['RAW_POST_DATA'] = ''
-        post :update, params: { id: account.id }
+        post :update, params: { id: account.id }, body: ''
       end
 
       it 'returns http client error' do
@@ -56,8 +54,7 @@ RSpec.describe Api::SalmonController, type: :controller do
         service = double(call: false)
         allow(VerifySalmonService).to receive(:new).and_return(service)
 
-        request.env['RAW_POST_DATA'] = File.read(File.join(Rails.root, 'spec', 'fixtures', 'salmon', 'mention.xml'))
-        post :update, params: { id: account.id }
+        post :update, params: { id: account.id }, body: File.read(Rails.root.join('spec', 'fixtures', 'salmon', 'mention.xml'))
       end
 
       it 'returns http client error' do
diff --git a/spec/controllers/api/subscriptions_controller_spec.rb b/spec/controllers/api/subscriptions_controller_spec.rb
index 48eb1fc64c951d04ae4f1a3e5be18d7054c70b01..7a4252fe6737ec9778099e0ad4c6a3c2c2bd07a5 100644
--- a/spec/controllers/api/subscriptions_controller_spec.rb
+++ b/spec/controllers/api/subscriptions_controller_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe Api::SubscriptionsController, type: :controller do
   end
 
   describe 'POST #update' do
-    let(:feed) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'push', 'feed.atom')) }
+    let(:feed) { File.read(Rails.root.join('spec', 'fixtures', 'push', 'feed.atom')) }
 
     before do
       stub_request(:post, "https://quitter.no/main/push/hub").to_return(:status => 200, :body => "", :headers => {})
@@ -53,9 +53,8 @@ RSpec.describe Api::SubscriptionsController, type: :controller do
       stub_request(:any, "https://mastodon.social/users/Gargron").to_return(status: 404)
 
       request.env['HTTP_X_HUB_SIGNATURE'] = "sha1=#{OpenSSL::HMAC.hexdigest('sha1', 'abc', feed)}"
-      request.env['RAW_POST_DATA'] = feed
 
-      post :update, params: { id: account.id }
+      post :update, params: { id: account.id }, body: feed
     end
 
     it 'returns http success' do
diff --git a/spec/controllers/api/v1/accounts/pins_controller_spec.rb b/spec/controllers/api/v1/accounts/pins_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c71935df21330a376ff85c7eb78b0fd37f553dd4
--- /dev/null
+++ b/spec/controllers/api/v1/accounts/pins_controller_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe Api::V1::Accounts::PinsController, type: :controller do
+  let(:john)  { Fabricate(:user, account: Fabricate(:account, username: 'john')) }
+  let(:kevin) { Fabricate(:user, account: Fabricate(:account, username: 'kevin')) }
+  let(:token) { Fabricate(:accessible_access_token, resource_owner_id: john.id, scopes: 'write:accounts') }
+
+  before do
+    kevin.account.followers << john.account
+    allow(controller).to receive(:doorkeeper_token) { token }
+  end
+
+  describe 'POST #create' do
+    subject { post :create, params: { account_id: kevin.account.id } }
+
+    it 'returns 200' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'creates account_pin' do
+      expect do
+        subject
+      end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(1)
+    end
+  end
+
+  describe 'DELETE #destroy' do
+    subject { delete :destroy, params: { account_id: kevin.account.id } }
+
+    before do
+      Fabricate(:account_pin, account: john.account, target_account: kevin.account)
+    end
+
+    it 'returns 200' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'destroys account_pin' do
+      expect do
+        subject
+      end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(-1)
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/accounts_controller_spec.rb b/spec/controllers/api/v1/accounts_controller_spec.rb
index 3e54e88a5b79e8cf82347af596c57508d1e32eb1..f5f65c000e54a8b66b9b4ad232b7e9f52f7a920b 100644
--- a/spec/controllers/api/v1/accounts_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts_controller_spec.rb
@@ -19,6 +19,40 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
     end
   end
 
+  describe 'POST #create' do
+    let(:app) { Fabricate(:application) }
+    let(:token) { Doorkeeper::AccessToken.find_or_create_for(app, nil, 'read write', nil, false) }
+    let(:agreement) { nil }
+
+    before do
+      post :create, params: { username: 'test', password: '12345678', email: 'hello@world.tld', agreement: agreement }
+    end
+
+    context 'given truthy agreement' do
+      let(:agreement) { 'true' }
+
+      it 'returns http success' do
+        expect(response).to have_http_status(200)
+      end
+
+      it 'returns a new access token as JSON' do
+        expect(body_as_json[:access_token]).to_not be_blank
+      end
+
+      it 'creates a user' do
+        user = User.find_by(email: 'hello@world.tld')
+        expect(user).to_not be_nil
+        expect(user.created_by_application_id).to eq app.id
+      end
+    end
+
+    context 'given no agreement' do
+      it 'returns http unprocessable entity' do
+        expect(response).to have_http_status(422)
+      end
+    end
+  end
+
   describe 'GET #show' do
     let(:scopes) { 'read:accounts' }
 
@@ -154,7 +188,7 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
 
     before do
       user.account.follow!(other_account)
-      post :mute, params: {id: other_account.id }
+      post :mute, params: { id: other_account.id }
     end
 
     it 'returns http success' do
@@ -182,7 +216,7 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
 
     before do
       user.account.follow!(other_account)
-      post :mute, params: {id: other_account.id, notifications: false }
+      post :mute, params: { id: other_account.id, notifications: false }
     end
 
     it 'returns http success' do
diff --git a/spec/controllers/api/v1/conversations_controller_spec.rb b/spec/controllers/api/v1/conversations_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..070f65061b5239fd2a6d94837abcfa8a53d8a88e
--- /dev/null
+++ b/spec/controllers/api/v1/conversations_controller_spec.rb
@@ -0,0 +1,37 @@
+require 'rails_helper'
+
+RSpec.describe Api::V1::ConversationsController, type: :controller do
+  render_views
+
+  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')) }
+
+  before do
+    allow(controller).to receive(:doorkeeper_token) { token }
+  end
+
+  describe 'GET #index' do
+    let(:scopes) { 'read:statuses' }
+
+    before do
+      PostStatusService.new.call(other.account, text: 'Hey @alice', visibility: 'direct')
+    end
+
+    it 'returns http success' do
+      get :index
+      expect(response).to have_http_status(200)
+    end
+
+    it 'returns pagination headers' do
+      get :index, params: { limit: 1 }
+      expect(response.headers['Link'].links.size).to eq(2)
+    end
+
+    it 'returns conversations' do
+      get :index
+      json = body_as_json
+      expect(json.size).to eq 1
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/endorsements_controller_spec.rb b/spec/controllers/api/v1/endorsements_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ad5ff400f5e0c211db65ab98f724265489fa07cc
--- /dev/null
+++ b/spec/controllers/api/v1/endorsements_controller_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe Api::V1::EndorsementsController, type: :controller do
+  let(:user)  { Fabricate(:user) }
+  let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
+
+  describe 'GET #index' do
+    it 'returns 200' do
+      allow(controller).to receive(:doorkeeper_token) { token }
+      get :index
+
+      expect(response).to have_http_status(200)
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/favourites_controller_spec.rb b/spec/controllers/api/v1/favourites_controller_spec.rb
index 2bdf927f21f7db2b75451ae87da9339896fefae3..231f765008ed2792cc9d51342dea95b680a0c142 100644
--- a/spec/controllers/api/v1/favourites_controller_spec.rb
+++ b/spec/controllers/api/v1/favourites_controller_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe Api::V1::FavouritesController, type: :controller do
           get :index, params: { limit: 1 }
 
           expect(response.headers['Link'].find_link(['rel', 'next']).href).to eq "http://test.host/api/v1/favourites?limit=1&max_id=#{favourite.id}"
-          expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq "http://test.host/api/v1/favourites?limit=1&since_id=#{favourite.id}"
+          expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq "http://test.host/api/v1/favourites?limit=1&min_id=#{favourite.id}"
         end
 
         it 'does not add pagination headers if not necessary' do
diff --git a/spec/controllers/api/v1/instances/activity_controller_spec.rb b/spec/controllers/api/v1/instances/activity_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..159792ee0196becb941b560e458457367897fa63
--- /dev/null
+++ b/spec/controllers/api/v1/instances/activity_controller_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe Api::V1::Instances::ActivityController, type: :controller do
+  describe 'GET #show' do
+    it 'returns 200' do
+      get :show
+      expect(response).to have_http_status(200)
+    end
+
+    context '!Setting.activity_api_enabled' do
+      it 'returns 404' do
+        Setting.activity_api_enabled = false
+
+        get :show
+        expect(response).to have_http_status(404)
+      end
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/instances/peers_controller_spec.rb b/spec/controllers/api/v1/instances/peers_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..12a214a83ac890f4f6ce3618ab248cec5f9d5a22
--- /dev/null
+++ b/spec/controllers/api/v1/instances/peers_controller_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe Api::V1::Instances::PeersController, type: :controller do
+  describe 'GET #index' do
+    it 'returns 200' do
+      get :index
+      expect(response).to have_http_status(200)
+    end
+
+    context '!Setting.peers_api_enabled' do
+      it 'returns 404' do
+        Setting.peers_api_enabled = false
+
+        get :index
+        expect(response).to have_http_status(404)
+      end
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/media_controller_spec.rb b/spec/controllers/api/v1/media_controller_spec.rb
index f01fcd9424c74e2efca6d386f959f860a4fd9b68..4e3037208431268324a19642297ccaa7172ca63f 100644
--- a/spec/controllers/api/v1/media_controller_spec.rb
+++ b/spec/controllers/api/v1/media_controller_spec.rb
@@ -84,19 +84,17 @@ RSpec.describe Api::V1::MediaController, type: :controller do
         post :create, params: { file: fixture_file_upload('files/attachment.webm', 'video/webm') }
       end
 
-      xit 'returns http success' do
+      it do
+        # returns http success
         expect(response).to have_http_status(200)
-      end
 
-      xit 'creates a media attachment' do
+        # creates a media attachment
         expect(MediaAttachment.first).to_not be_nil
-      end
 
-      xit 'uploads a file' do
+        # uploads a file
         expect(MediaAttachment.first).to have_attached_file(:file)
-      end
 
-      xit 'returns media ID in JSON' do
+        # returns media ID in JSON
         expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s
       end
     end
diff --git a/spec/controllers/api/v1/mutes_controller_spec.rb b/spec/controllers/api/v1/mutes_controller_spec.rb
index f9603b7ff1e645af72e9421c70f38ade1d32c454..a2b814a690d43b95d94194ad5a04a55a16d12faf 100644
--- a/spec/controllers/api/v1/mutes_controller_spec.rb
+++ b/spec/controllers/api/v1/mutes_controller_spec.rb
@@ -3,19 +3,61 @@ require 'rails_helper'
 RSpec.describe Api::V1::MutesController, type: :controller do
   render_views
 
-  let(:user)  { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
-  let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:mutes') }
+  let(:user)   { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
+  let(:scopes) { 'read:mutes' }
+  let(:token)  { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
 
-  before do
-    Fabricate(:mute, account: user.account, hide_notifications: false)
-    allow(controller).to receive(:doorkeeper_token) { token }
-  end
+  before { allow(controller).to receive(:doorkeeper_token) { token } }
 
   describe 'GET #index' do
-    it 'returns http success' do
+    it 'limits according to limit parameter' do
+      2.times.map { Fabricate(:mute, account: user.account) }
       get :index, params: { limit: 1 }
+      expect(body_as_json.size).to eq 1
+    end
+
+    it 'queries mutes in range according to max_id' do
+      mutes = 2.times.map { Fabricate(:mute, account: user.account) }
+
+      get :index, params: { max_id: mutes[1] }
 
+      expect(body_as_json.size).to eq 1
+      expect(body_as_json[0][:id]).to eq mutes[0].target_account_id.to_s
+    end
+
+    it 'queries mutes in range according to since_id' do
+      mutes = 2.times.map { Fabricate(:mute, account: user.account) }
+
+      get :index, params: { since_id: mutes[0] }
+
+      expect(body_as_json.size).to eq 1
+      expect(body_as_json[0][:id]).to eq mutes[1].target_account_id.to_s
+    end
+
+    it 'sets pagination header for next path' do
+      mutes = 2.times.map { Fabricate(:mute, account: user.account) }
+      get :index, params: { limit: 1, since_id: mutes[0] }
+      expect(response.headers['Link'].find_link(['rel', 'next']).href).to eq api_v1_mutes_url(limit: 1, max_id: mutes[1])
+    end
+
+    it 'sets pagination header for previous path' do
+      mute = Fabricate(:mute, account: user.account)
+      get :index
+      expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq api_v1_mutes_url(since_id: mute)
+    end
+
+    it 'returns http success' do
+      get :index
       expect(response).to have_http_status(200)
     end
+
+    context 'with wrong scopes' do
+      let(:scopes) { 'write:mutes' }
+
+      it 'returns http forbidden' do
+        get :index
+        expect(response).to have_http_status(403)
+      end
+    end
   end
 end
diff --git a/spec/controllers/api/v1/notifications_controller_spec.rb b/spec/controllers/api/v1/notifications_controller_spec.rb
index 9f679cb8a7594e8a247b74efe6c04dbfedbd1bca..d0f82e79febbc85cbf5b053cc8878b3b89628946 100644
--- a/spec/controllers/api/v1/notifications_controller_spec.rb
+++ b/spec/controllers/api/v1/notifications_controller_spec.rb
@@ -50,9 +50,9 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do
     let(:scopes) { 'read:notifications' }
 
     before do
-      first_status = PostStatusService.new.call(user.account, 'Test')
+      first_status = PostStatusService.new.call(user.account, text: 'Test')
       @reblog_of_first_status = ReblogService.new.call(other.account, first_status)
-      mentioning_status = PostStatusService.new.call(other.account, 'Hello @alice')
+      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)
       @follow = FollowService.new.call(other.account, 'alice')
diff --git a/spec/controllers/api/v1/reports_controller_spec.rb b/spec/controllers/api/v1/reports_controller_spec.rb
index ac93998c6901d0b2be8ad4b7df1593416ba57d65..a3596cf8a0387640c4deca777327d3ac3f6f2e21 100644
--- a/spec/controllers/api/v1/reports_controller_spec.rb
+++ b/spec/controllers/api/v1/reports_controller_spec.rb
@@ -12,16 +12,6 @@ RSpec.describe Api::V1::ReportsController, type: :controller do
     allow(controller).to receive(:doorkeeper_token) { token }
   end
 
-  describe 'GET #index' do
-    let(:scopes) { 'read:reports' }
-
-    it 'returns http success' do
-      get :index
-
-      expect(response).to have_http_status(200)
-    end
-  end
-
   describe 'POST #create' do
     let(:scopes)  { 'write:reports' }
     let!(:status) { Fabricate(:status) }
diff --git a/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb b/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb
index 23b5d7de92e39f7a63d89e3c2527b1edd1d3ebfe..40f75c700f592ccbe809398a90775fb32bcf4354 100644
--- a/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb
+++ b/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb
@@ -25,7 +25,6 @@ RSpec.describe Api::V1::Statuses::FavouritedByAccountsController, type: :control
         expect(response.headers['Link'].links.size).to eq(2)
       end
     end
-
   end
 
   context 'without an oauth token' do
diff --git a/spec/controllers/api/v1/streaming_controller_spec.rb b/spec/controllers/api/v1/streaming_controller_spec.rb
index daf2807e7f1953a553cae6cbf6d1e624e2b3cde7..4ab409a54103bcf20a95cb9070db04f4119d52a6 100644
--- a/spec/controllers/api/v1/streaming_controller_spec.rb
+++ b/spec/controllers/api/v1/streaming_controller_spec.rb
@@ -31,7 +31,7 @@ describe Api::V1::StreamingController do
 
     describe 'GET #index' do
       it 'redirects to streaming host' do
-        get :index, params: {access_token: 'deadbeef', stream: 'public'}
+        get :index, params: { access_token: 'deadbeef', stream: 'public' }
         expect(response).to have_http_status(301)
         request_uri = URI.parse(request.url)
         redirect_to_uri = URI.parse(response.location)
@@ -42,5 +42,4 @@ describe Api::V1::StreamingController do
       end
     end
   end
-
 end
diff --git a/spec/controllers/api/v1/timelines/direct_controller_spec.rb b/spec/controllers/api/v1/timelines/direct_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a22c2cbea598b386671e8037c2e46b595d012718
--- /dev/null
+++ b/spec/controllers/api/v1/timelines/direct_controller_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe Api::V1::Timelines::DirectController, type: :controller do
+  let(:user)  { Fabricate(:user) }
+  let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') }
+
+  describe 'GET #show' do
+    it 'returns 200' do
+      allow(controller).to receive(:doorkeeper_token) { token }
+      get :show
+
+      expect(response).to have_http_status(200)
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/timelines/home_controller_spec.rb b/spec/controllers/api/v1/timelines/home_controller_spec.rb
index a667c33fadb8126bf8212bf606cb43f1501c4793..e953e46495326b6651fb0c6a8f2282c11a8a3b89 100644
--- a/spec/controllers/api/v1/timelines/home_controller_spec.rb
+++ b/spec/controllers/api/v1/timelines/home_controller_spec.rb
@@ -5,7 +5,7 @@ require 'rails_helper'
 describe Api::V1::Timelines::HomeController do
   render_views
 
-  let(:user)  { Fabricate(:user, account: Fabricate(:account, username: 'alice'), current_sign_in_at: 1.day.ago) }
+  let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice'), current_sign_in_at: 1.day.ago) }
 
   before do
     allow(controller).to receive(:doorkeeper_token) { token }
@@ -17,7 +17,7 @@ describe Api::V1::Timelines::HomeController do
     describe 'GET #show' do
       before do
         follow = Fabricate(:follow, account: user.account)
-        PostStatusService.new.call(follow.target_account, 'New status for user home timeline.')
+        PostStatusService.new.call(follow.target_account, text: 'New status for user home timeline.')
       end
 
       it 'returns http success' do
diff --git a/spec/controllers/api/v1/timelines/list_controller_spec.rb b/spec/controllers/api/v1/timelines/list_controller_spec.rb
index 93a2be6e6cd747aa38b4392c034efecc9d848fdb..45e4bf34c86e807db9d431eb5c9ddb8fec9f35fd 100644
--- a/spec/controllers/api/v1/timelines/list_controller_spec.rb
+++ b/spec/controllers/api/v1/timelines/list_controller_spec.rb
@@ -19,7 +19,7 @@ describe Api::V1::Timelines::ListController do
       before do
         follow = Fabricate(:follow, account: user.account)
         list.accounts << follow.target_account
-        PostStatusService.new.call(follow.target_account, 'New status for user home timeline.')
+        PostStatusService.new.call(follow.target_account, text: 'New status for user home timeline.')
       end
 
       it 'returns http success' do
diff --git a/spec/controllers/api/v1/timelines/public_controller_spec.rb b/spec/controllers/api/v1/timelines/public_controller_spec.rb
index 68d87bbcbd1848024347faf22ee2ad4c527b2fad..737aedba6fd03afaf4622b3cfb21ee0ae4bd0e50 100644
--- a/spec/controllers/api/v1/timelines/public_controller_spec.rb
+++ b/spec/controllers/api/v1/timelines/public_controller_spec.rb
@@ -5,7 +5,7 @@ require 'rails_helper'
 describe Api::V1::Timelines::PublicController do
   render_views
 
-  let(:user)  { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
+  let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
 
   before do
     allow(controller).to receive(:doorkeeper_token) { token }
@@ -16,7 +16,7 @@ describe Api::V1::Timelines::PublicController do
 
     describe 'GET #show' do
       before do
-        PostStatusService.new.call(user.account, 'New status from user for federated public timeline.')
+        PostStatusService.new.call(user.account, text: 'New status from user for federated public timeline.')
       end
 
       it 'returns http success' do
@@ -29,7 +29,7 @@ describe Api::V1::Timelines::PublicController do
 
     describe 'GET #show with local only' do
       before do
-        PostStatusService.new.call(user.account, 'New status from user for local public timeline.')
+        PostStatusService.new.call(user.account, text: 'New status from user for local public timeline.')
       end
 
       it 'returns http success' do
diff --git a/spec/controllers/api/v1/timelines/tag_controller_spec.rb b/spec/controllers/api/v1/timelines/tag_controller_spec.rb
index 472779f5456d98c835576236d50841d83fcfc349..f71ca2a399d2310031a1d91ca433161fafa2e130 100644
--- a/spec/controllers/api/v1/timelines/tag_controller_spec.rb
+++ b/spec/controllers/api/v1/timelines/tag_controller_spec.rb
@@ -16,7 +16,7 @@ describe Api::V1::Timelines::TagController do
 
     describe 'GET #show' do
       before do
-        PostStatusService.new.call(user.account, 'It is a #test')
+        PostStatusService.new.call(user.account, text: 'It is a #test')
       end
 
       it 'returns http success' do
diff --git a/spec/controllers/api/web/embeds_controller_spec.rb b/spec/controllers/api/web/embeds_controller_spec.rb
index 6b7297189aff1f619e62ed1c25315b252160e28b..a8fc1718f60686efc658c77dac6e7968be1a5d0f 100644
--- a/spec/controllers/api/web/embeds_controller_spec.rb
+++ b/spec/controllers/api/web/embeds_controller_spec.rb
@@ -14,7 +14,7 @@ describe Api::Web::EmbedsController do
 
     context 'when successfully finds status' do
       let(:status) { Fabricate(:status) }
-      let(:url) { "http://#{ Rails.configuration.x.web_domain }/@#{status.account.username}/#{status.id}" }
+      let(:url) { "http://#{Rails.configuration.x.web_domain}/@#{status.account.username}/#{status.id}" }
 
       it 'returns a right response' do
         expect(response).to have_http_status :ok
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index c6c78d3f7181161d2c5ec1890bd49b89cad940ab..33cc7108716d46f9adaf7ca1dfa7a291fadea746 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -92,6 +92,39 @@ describe ApplicationController, type: :controller do
     end
   end
 
+  describe 'helper_method :current_theme' do
+    it 'returns "default" when theme wasn\'t changed in admin settings' do
+      allow(Setting).to receive(:default_settings).and_return({ 'theme' => 'default' })
+
+      expect(controller.view_context.current_theme).to eq 'default'
+    end
+
+    it 'returns instances\'s theme when user is not signed in' do
+      allow(Setting).to receive(:[]).with('theme').and_return 'contrast'
+
+      expect(controller.view_context.current_theme).to eq 'contrast'
+    end
+
+    it 'returns instances\'s default theme when user didn\'t set theme' do
+      current_user = Fabricate(:user)
+      sign_in current_user
+
+      allow(Setting).to receive(:[]).with('theme').and_return 'contrast'
+
+      expect(controller.view_context.current_theme).to eq 'contrast'
+    end
+
+    it 'returns user\'s theme when it is set' do
+      current_user = Fabricate(:user)
+      current_user.settings['theme'] = 'mastodon-light'
+      sign_in current_user
+
+      allow(Setting).to receive(:[]).with('theme').and_return 'contrast'
+
+      expect(controller.view_context.current_theme).to eq 'mastodon-light'
+    end
+  end
+
   context 'ActionController::RoutingError' do
     subject do
       routes.draw { get 'routing_error' => 'anonymous#routing_error' }
@@ -164,7 +197,7 @@ describe ApplicationController, type: :controller do
   describe 'raise_not_found' do
     it 'raises error' do
       controller.params[:unmatched_route] = 'unmatched'
-      expect{ controller.raise_not_found }.to raise_error(ActionController::RoutingError, 'No route matches unmatched')
+      expect { controller.raise_not_found }.to raise_error(ActionController::RoutingError, 'No route matches unmatched')
     end
   end
 
diff --git a/spec/controllers/auth/confirmations_controller_spec.rb b/spec/controllers/auth/confirmations_controller_spec.rb
index 35eed4f513ff8eab51faf6b9b8866c81831050cb..e9a471fc5a9e2700beb7f462526bac3b0adbbfb7 100644
--- a/spec/controllers/auth/confirmations_controller_spec.rb
+++ b/spec/controllers/auth/confirmations_controller_spec.rb
@@ -67,7 +67,7 @@ describe Auth::ConfirmationsController, type: :controller do
   end
 
   describe 'PATCH #finish_signup' do
-    subject { patch :finish_signup, params: { user: { email: email }} }
+    subject { patch :finish_signup, params: { user: { email: email } } }
 
     let(:user) { Fabricate(:user) }
     before do
diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb
index 97719a606af26840959a225aadea660e676c728a..71fcc1a6e3d2a65b63a313455436446d876670fc 100644
--- a/spec/controllers/auth/sessions_controller_spec.rb
+++ b/spec/controllers/auth/sessions_controller_spec.rb
@@ -30,6 +30,13 @@ RSpec.describe Auth::SessionsController, type: :controller do
 
         expect(response).to redirect_to(new_user_session_path)
       end
+
+      it 'does not delete redirect location with continue=true' do
+        sign_in(user, scope: :user)
+        controller.store_location_for(:user, '/authorize')
+        delete :destroy, params: { continue: 'true' }
+        expect(controller.stored_location_for(:user)).to eq '/authorize'
+      end
     end
 
     context 'with a suspended user' do
@@ -48,7 +55,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
       request.env['devise.mapping'] = Devise.mappings[:user]
     end
 
-    context 'using PAM authentication' do
+    context 'using PAM authentication', if: ENV['PAM_ENABLED'] == 'true' do
       context 'using a valid password' do
         before do
           post :create, params: { user: { email: "pam_user1", password: '123456' } }
diff --git a/spec/controllers/authorize_follows_controller_spec.rb b/spec/controllers/authorize_interactions_controller_spec.rb
similarity index 71%
rename from spec/controllers/authorize_follows_controller_spec.rb
rename to spec/controllers/authorize_interactions_controller_spec.rb
index 52971c72478a9ef62e83979ede8e8c36348f932e..ce4257b68dcda85e45156d0e57c99f186976a58c 100644
--- a/spec/controllers/authorize_follows_controller_spec.rb
+++ b/spec/controllers/authorize_interactions_controller_spec.rb
@@ -2,7 +2,7 @@
 
 require 'rails_helper'
 
-describe AuthorizeFollowsController do
+describe AuthorizeInteractionsController do
   render_views
 
   describe 'GET #show' do
@@ -39,19 +39,19 @@ describe AuthorizeFollowsController do
         expect(service).to have_received(:call).with('missing@hostname')
       end
 
-      it 'sets account from url' do
+      it 'sets resource from url' do
         account = Account.new
         service = double
-        allow(FetchRemoteAccountService).to receive(:new).and_return(service)
+        allow(ResolveURLService).to receive(:new).and_return(service)
         allow(service).to receive(:call).with('http://example.com').and_return(account)
 
         get :show, params: { acct: 'http://example.com' }
 
         expect(response).to have_http_status(200)
-        expect(assigns(:account)).to eq account
+        expect(assigns(:resource)).to eq account
       end
 
-      it 'sets account from acct uri' do
+      it 'sets resource from acct uri' do
         account = Account.new
         service = double
         allow(ResolveAccountService).to receive(:new).and_return(service)
@@ -60,7 +60,7 @@ describe AuthorizeFollowsController do
         get :show, params: { acct: 'acct:found@hostname' }
 
         expect(response).to have_http_status(200)
-        expect(assigns(:account)).to eq account
+        expect(assigns(:resource)).to eq account
       end
     end
   end
@@ -75,8 +75,8 @@ describe AuthorizeFollowsController do
     end
 
     describe 'when signed in' do
-      let(:user) { Fabricate(:user) }
-      let(:account) { Fabricate(:account, user: user) }
+      let!(:user) { Fabricate(:user) }
+      let!(:account) { user.account }
 
       before do
         sign_in(user)
@@ -84,25 +84,28 @@ describe AuthorizeFollowsController do
 
       it 'shows error when account not found' do
         service = double
-        allow(FollowService).to receive(:new).and_return(service)
-        allow(service).to receive(:call).with(account, 'user@hostname').and_return(nil)
+
+        allow(ResolveAccountService).to receive(:new).and_return(service)
+        allow(service).to receive(:call).with('user@hostname').and_return(nil)
 
         post :create, params: { acct: 'acct:user@hostname' }
 
-        expect(service).to have_received(:call).with(account, 'user@hostname')
         expect(response).to render_template(:error)
       end
 
       it 'follows account when found' do
         target_account = Fabricate(:account)
-        result_account = double(target_account: target_account)
         service = double
-        allow(FollowService).to receive(:new).and_return(service)
-        allow(service).to receive(:call).with(account, 'user@hostname').and_return(result_account)
+
+        allow(ResolveAccountService).to receive(:new).and_return(service)
+        allow(service).to receive(:call).with('user@hostname').and_return(target_account)
+        allow(service).to receive(:call).with(target_account, skip_webfinger: true).and_return(target_account)
+
 
         post :create, params: { acct: 'acct:user@hostname' }
 
-        expect(service).to have_received(:call).with(account, 'user@hostname')
+        expect(service).to have_received(:call).with(target_account, skip_webfinger: true)
+        expect(account.following?(target_account)).to be true
         expect(response).to render_template(:success)
       end
     end
diff --git a/spec/controllers/concerns/accountable_concern_spec.rb b/spec/controllers/concerns/accountable_concern_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e3c06b4947953c1c8e5f5c484613f8149e06ecf0
--- /dev/null
+++ b/spec/controllers/concerns/accountable_concern_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe AccountableConcern do
+  class Hoge
+    include AccountableConcern
+    attr_reader :current_account
+
+    def initialize(current_account)
+      @current_account = current_account
+    end
+  end
+
+  let(:user)   { Fabricate(:user, account: Fabricate(:account)) }
+  let(:target) { Fabricate(:user, account: Fabricate(:account)) }
+  let(:hoge)   { Hoge.new(user.account) }
+
+  describe '#log_action' do
+    it 'creates Admin::ActionLog' do
+      expect do
+        hoge.log_action(:create, target.account)
+      end.to change { Admin::ActionLog.count }.by(1)
+    end
+  end
+end
diff --git a/spec/controllers/concerns/export_controller_concern_spec.rb b/spec/controllers/concerns/export_controller_concern_spec.rb
index 6a13db69d65f3860b0860373d8f0d7cda53cdf7c..e5861c801f54448442d09ffeebbec2c72f69de20 100644
--- a/spec/controllers/concerns/export_controller_concern_spec.rb
+++ b/spec/controllers/concerns/export_controller_concern_spec.rb
@@ -8,6 +8,7 @@ describe ApplicationController, type: :controller do
     def index
       send_export_file
     end
+
     def export_data
       @export.account.username
     end
diff --git a/spec/controllers/concerns/localized_spec.rb b/spec/controllers/concerns/localized_spec.rb
index 8c80b7d2a8df087cce9f623ecdb7759ae6f47ab5..76c3de1183d430093dc76038e9e728392c8c4fda 100644
--- a/spec/controllers/concerns/localized_spec.rb
+++ b/spec/controllers/concerns/localized_spec.rb
@@ -28,7 +28,7 @@ describe ApplicationController, type: :controller do
       expect(I18n.locale).to eq :fa
     end
 
-    it 'sets available and compatible langauge if none of available languages are preferred' do
+    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
diff --git a/spec/controllers/concerns/signature_verification_spec.rb b/spec/controllers/concerns/signature_verification_spec.rb
index 64648621e04ae10390ae3f8e9fc3b8175774fb80..72069009716267e8b3b086f36c8c9b131705782a 100644
--- a/spec/controllers/concerns/signature_verification_spec.rb
+++ b/spec/controllers/concerns/signature_verification_spec.rb
@@ -73,6 +73,30 @@ describe ApplicationController, type: :controller do
       end
     end
 
+    context 'with request older than a day' do
+      before do
+        get :success
+
+        fake_request = Request.new(:get, request.url)
+        fake_request.add_headers({ 'Date' => 2.days.ago.utc.httpdate })
+        fake_request.on_behalf_of(author)
+
+        request.headers.merge!(fake_request.headers)
+      end
+
+      describe '#signed_request?' do
+        it 'returns true' do
+          expect(controller.signed_request?).to be true
+        end
+      end
+
+      describe '#signed_request_account' do
+        it 'returns nil' do
+          expect(controller.signed_request_account).to be_nil
+        end
+      end
+    end
+
     context 'with body' do
       before do
         post :success, body: 'Hello world'
@@ -105,7 +129,7 @@ describe ApplicationController, type: :controller do
         end
 
         it 'returns nil when body has been tampered' do
-          request.headers['RAW_POST_DATA'] = 'doo doo doo'
+          post :success, body: 'doo doo doo'
           expect(controller.signed_request_account).to be_nil
         end
       end
diff --git a/spec/controllers/emojis_controller_spec.rb b/spec/controllers/emojis_controller_spec.rb
index 68bae256d7b1c400af05cb2e0bca9586a9ec5716..fbbd11f64806d4927298b06003097fdbed63ba67 100644
--- a/spec/controllers/emojis_controller_spec.rb
+++ b/spec/controllers/emojis_controller_spec.rb
@@ -6,11 +6,11 @@ describe EmojisController do
   let(:emoji) { Fabricate(:custom_emoji) }
 
   describe 'GET #show' do
-    subject(:responce) { get :show, params: { id: emoji.id, format: :json } }
+    subject(:response) { get :show, params: { id: emoji.id, format: :json } }
     subject(:body) { JSON.parse(response.body, symbolize_names: true) }
 
     it 'returns the right response' do
-      expect(responce).to have_http_status 200
+      expect(response).to have_http_status 200
       expect(body[:name]).to eq ':coolcat:'
     end
   end
diff --git a/spec/controllers/intents_controller_spec.rb b/spec/controllers/intents_controller_spec.rb
index 3dde7f835bffc83e7f60cfa21443dac8003022e2..ddfd5ea365639e082ca614c531fc0aae4e324970 100644
--- a/spec/controllers/intents_controller_spec.rb
+++ b/spec/controllers/intents_controller_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe IntentsController, type: :controller do
       context 'when host is follow' do
         let(:uri) { 'web+mastodon://follow?uri=test' }
 
-        it { is_expected.to redirect_to authorize_follow_path(acct: 'test') }
+        it { is_expected.to redirect_to authorize_interaction_path(uri: 'test') }
       end
 
       context 'when host is share' do
diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb
index 9f5ab67c303144cf99e38e4b3b10e78d8d055fa8..76e617e6b69139d5639e26dafe6b83208236d29e 100644
--- a/spec/controllers/invites_controller_spec.rb
+++ b/spec/controllers/invites_controller_spec.rb
@@ -43,7 +43,7 @@ describe InvitesController do
       let(:user) { Fabricate(:user, moderator: false, admin: true) }
 
       it 'succeeds to create a invite' do
-        expect{ subject }.to change { Invite.count }.by(1)
+        expect { subject }.to change { Invite.count }.by(1)
         expect(subject).to redirect_to invites_path
         expect(Invite.last).to have_attributes(user_id: user.id, max_uses: 10)
       end
diff --git a/spec/controllers/oauth/authorizations_controller_spec.rb b/spec/controllers/oauth/authorizations_controller_spec.rb
index 91c2d03ef05e4b9c7265b6b88129a6055aa42396..a84260a54d2abbff1a3a67804e9738a11d3a69a6 100644
--- a/spec/controllers/oauth/authorizations_controller_spec.rb
+++ b/spec/controllers/oauth/authorizations_controller_spec.rb
@@ -5,23 +5,25 @@ require 'rails_helper'
 RSpec.describe Oauth::AuthorizationsController, type: :controller do
   render_views
 
-  let(:app) { Doorkeeper::Application.create!(name: 'test', redirect_uri: 'http://localhost/') }
+  let(:app) { Doorkeeper::Application.create!(name: 'test', redirect_uri: 'http://localhost/', scopes: 'read') }
 
   describe 'GET #new' do
     subject do
-      get :new, params: { client_id: app.uid, response_type: 'code', redirect_uri: 'http://localhost/' }
+      get :new, params: { client_id: app.uid, response_type: 'code', redirect_uri: 'http://localhost/', scope: 'read' }
     end
 
     shared_examples 'stores location for user' do
       it 'stores location for user' do
         subject
-        expect(controller.stored_location_for(:user)).to eq "/oauth/authorize?client_id=#{app.uid}&redirect_uri=http%3A%2F%2Flocalhost%2F&response_type=code"
+        expect(controller.stored_location_for(:user)).to eq "/oauth/authorize?client_id=#{app.uid}&redirect_uri=http%3A%2F%2Flocalhost%2F&response_type=code&scope=read"
       end
     end
 
     context 'when signed in' do
+      let!(:user) { Fabricate(:user) }
+
       before do
-        sign_in Fabricate(:user), scope: :user
+        sign_in user, scope: :user
       end
 
       it 'returns http success' do
@@ -35,6 +37,28 @@ RSpec.describe Oauth::AuthorizationsController, type: :controller do
       end
 
       include_examples 'stores location for user'
+
+      context 'when app is already authorized' do
+        before do
+          Doorkeeper::AccessToken.find_or_create_for(
+            app,
+            user.id,
+            app.scopes,
+            Doorkeeper.configuration.access_token_expires_in,
+            Doorkeeper.configuration.refresh_token_enabled?
+          )
+        end
+
+        it 'redirects to callback' do
+          subject
+          expect(response).to redirect_to(/\A#{app.redirect_uri}/)
+        end
+
+        it 'does not redirect to callback with force_login=true' do
+          get :new, params: { client_id: app.uid, response_type: 'code', redirect_uri: 'http://localhost/', scope: 'read', force_login: 'true' }
+          expect(response.body).to match(/Authorize/)
+        end
+      end
     end
 
     context 'when not signed in' do
diff --git a/spec/controllers/remote_interaction_controller_spec.rb b/spec/controllers/remote_interaction_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bb0074b11482185e85a79510212483555a90f222
--- /dev/null
+++ b/spec/controllers/remote_interaction_controller_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe RemoteInteractionController, type: :controller do
+  render_views
+
+  let(:status) { Fabricate(:status) }
+
+  describe 'GET #new' do
+    it 'returns 200' do
+      get :new, params: { id: status.id }
+      expect(response).to have_http_status(200)
+    end
+  end
+
+  describe 'POST #create' do
+    context '@remote_follow is valid' do
+      it 'returns 302' do
+        allow_any_instance_of(RemoteFollow).to receive(:valid?) { true }
+        allow_any_instance_of(RemoteFollow).to receive(:addressable_template) do
+          Addressable::Template.new('https://hoge.com')
+        end
+
+        post :create, params: { id: status.id, remote_follow: { acct: '@hoge' } }
+        expect(response).to have_http_status(302)
+      end
+    end
+
+    context '@remote_follow is invalid' do
+      it 'returns 200' do
+        allow_any_instance_of(RemoteFollow).to receive(:valid?) { false }
+        post :create, params: { id: status.id, remote_follow: { acct: '@hoge' } }
+
+        expect(response).to have_http_status(200)
+      end
+    end
+  end
+end
diff --git a/spec/controllers/remote_unfollows_controller_spec.rb b/spec/controllers/remote_unfollows_controller_spec.rb
index 223ed64af62b9dea45ecc529c93d507fcb39b075..a1a55ede0b19906a74904fe5b5566409df7cd154 100644
--- a/spec/controllers/remote_unfollows_controller_spec.rb
+++ b/spec/controllers/remote_unfollows_controller_spec.rb
@@ -14,11 +14,11 @@ describe RemoteUnfollowsController do
     before do
       sign_in current_user
       current_account.follow!(remote_account)
-      stub_request(:post, 'http://example.com/inbox'){ { status: 200 } }
+      stub_request(:post, 'http://example.com/inbox') { { status: 200 } }
     end
 
     context 'when successfully unfollow remote account' do
-      let(:acct) {"acct:#{ remote_account.username }@#{ remote_account.domain }"}
+      let(:acct) { "acct:#{remote_account.username}@#{remote_account.domain}" }
 
       it do
         is_expected.to render_template :success
@@ -27,7 +27,7 @@ describe RemoteUnfollowsController do
     end
 
     context 'when fails to unfollow remote account' do
-      let(:acct) {"acct:#{ remote_account.username + '_test' }@#{ remote_account.domain }"}
+      let(:acct) { "acct:#{remote_account.username + '_test'}@#{remote_account.domain}" }
 
       it do
         is_expected.to render_template :error
diff --git a/spec/controllers/settings/applications_controller_spec.rb b/spec/controllers/settings/applications_controller_spec.rb
index f87107695fe7c8ecb4431973a7b509f4e99169da..29c278148463f887915b0be770ed44c9764ff7cc 100644
--- a/spec/controllers/settings/applications_controller_spec.rb
+++ b/spec/controllers/settings/applications_controller_spec.rb
@@ -21,7 +21,6 @@ describe Settings::ApplicationsController do
     end
   end
 
-
   describe 'GET #show' do
     it 'returns http success' do
       get :show, params: { id: app.id }
@@ -48,13 +47,13 @@ describe Settings::ApplicationsController do
     context 'success (passed scopes as a String)' do
       def call_create
         post :create, params: {
-               doorkeeper_application: {
-                 name: 'My New App',
-                 redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
-                 website: 'http://google.com',
-                 scopes: 'read write follow'
-               }
-             }
+          doorkeeper_application: {
+            name: 'My New App',
+            redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
+            website: 'http://google.com',
+            scopes: 'read write follow'
+          }
+        }
         response
       end
 
@@ -70,13 +69,13 @@ describe Settings::ApplicationsController do
     context 'success (passed scopes as an Array)' do
       def call_create
         post :create, params: {
-               doorkeeper_application: {
-                 name: 'My New App',
-                 redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
-                 website: 'http://google.com',
-                 scopes: [ 'read', 'write', 'follow' ]
-               }
-             }
+          doorkeeper_application: {
+            name: 'My New App',
+            redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
+            website: 'http://google.com',
+            scopes: [ 'read', 'write', 'follow' ]
+          }
+        }
         response
       end
 
@@ -92,13 +91,13 @@ describe Settings::ApplicationsController do
     context 'failure' do
       before do
         post :create, params: {
-               doorkeeper_application: {
-                 name: '',
-                 redirect_uri: '',
-                 website: '',
-                 scopes: []
-               }
-             }
+          doorkeeper_application: {
+            name: '',
+            redirect_uri: '',
+            website: '',
+            scopes: []
+          }
+        }
       end
 
       it 'returns http success' do
@@ -121,9 +120,9 @@ describe Settings::ApplicationsController do
 
       def call_update
         patch :update, params: {
-                id: app.id,
-                doorkeeper_application: opts
-              }
+          id: app.id,
+          doorkeeper_application: opts
+        }
         response
       end
 
@@ -140,14 +139,14 @@ describe Settings::ApplicationsController do
     context 'failure' do
       before do
         patch :update, params: {
-                id: app.id,
-                doorkeeper_application: {
-                  name: '',
-                  redirect_uri: '',
-                  website: '',
-                  scopes: []
-                }
-              }
+          id: app.id,
+          doorkeeper_application: {
+            name: '',
+            redirect_uri: '',
+            website: '',
+            scopes: []
+          }
+        }
       end
 
       it 'returns http success' do
diff --git a/spec/controllers/settings/exports_controller_spec.rb b/spec/controllers/settings/exports_controller_spec.rb
index b7cab4d8f2b902d66e8cacc52368c934ef74b2c2..a46fe095d840553c525d0d516a7c4b949981dcab 100644
--- a/spec/controllers/settings/exports_controller_spec.rb
+++ b/spec/controllers/settings/exports_controller_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 
 describe Settings::ExportsController do
@@ -28,4 +30,23 @@ describe Settings::ExportsController do
       end
     end
   end
+
+  describe 'POST #create' do
+    before do
+      sign_in Fabricate(:user), scope: :user
+    end
+
+    it 'redirects to settings_export_path' do
+      post :create
+      expect(response).to redirect_to(settings_export_path)
+    end
+
+    it 'queues BackupWorker job by 1' do
+      Sidekiq::Testing.fake! do
+        expect do
+          post :create
+        end.to change(BackupWorker.jobs, :size).by(1)
+      end
+    end
+  end
 end
diff --git a/spec/controllers/settings/migrations_controller_spec.rb b/spec/controllers/settings/migrations_controller_spec.rb
index a621bcf1ce9999da803f391245ce8ae0acd3b20c..4d814a45e2977013e2042f25f5b8d8a48a24715c 100644
--- a/spec/controllers/settings/migrations_controller_spec.rb
+++ b/spec/controllers/settings/migrations_controller_spec.rb
@@ -10,7 +10,6 @@ describe Settings::MigrationsController do
   end
 
   describe 'GET #show' do
-
     context 'when user is not sign in' do
       subject { get :show }
 
@@ -45,7 +44,6 @@ describe Settings::MigrationsController do
   end
 
   describe 'PUT #update' do
-
     context 'when user is not sign in' do
       subject { put :update }
 
diff --git a/spec/controllers/settings/profiles_controller_spec.rb b/spec/controllers/settings/profiles_controller_spec.rb
index a453200af6efff4c8bce4eb4562d9f89b097200c..5b1fe3acad697e4c8878dd73d82b723de97469cb 100644
--- a/spec/controllers/settings/profiles_controller_spec.rb
+++ b/spec/controllers/settings/profiles_controller_spec.rb
@@ -26,4 +26,26 @@ RSpec.describe Settings::ProfilesController, type: :controller do
       expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
     end
   end
+
+  describe 'PUT #update with new profile image' do
+    it 'updates profile image' do
+      allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
+      account = Fabricate(:account, user: @user, display_name: 'AvatarTest')
+      expect(account.avatar.instance.avatar_file_name).to be_nil
+
+      put :update, params: { account: { avatar: fixture_file_upload('files/avatar.gif', 'image/gif') } }
+      expect(response).to redirect_to(settings_profile_path)
+      expect(account.reload.avatar.instance.avatar_file_name).not_to be_nil
+      expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
+    end
+  end
+
+  describe 'PUT #update with oversized image' do
+    it 'gives the user an error message' do
+      allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
+      account = Fabricate(:account, user: @user, display_name: 'AvatarTest')
+      put :update, params: { account: { avatar: fixture_file_upload('files/4096x4097.png', 'image/png') } }
+      expect(response.body).to include('images are not supported')
+    end
+  end
 end
diff --git a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb
index 7612bf90ece61d1644f61deb037bdc1ff7d2e86f..478f2458552a71f7d7e575ec3b7adcfa379ca77f 100644
--- a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb
+++ b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb
@@ -50,7 +50,7 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do
 
       describe 'when form_two_factor_confirmation parameter is not provided' do
         it 'raises ActionController::ParameterMissing' do
-          expect { post :create, params: { } }.to raise_error(ActionController::ParameterMissing)
+          expect { post :create, params: {} }.to raise_error(ActionController::ParameterMissing)
         end
       end
 
diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb
index b4f3c5a08192819b6f94122ac29aa3d17f3ec30d..1bb6636c603e8827e4f3e5594fdd01dbc30bd3a3 100644
--- a/spec/controllers/statuses_controller_spec.rb
+++ b/spec/controllers/statuses_controller_spec.rb
@@ -115,14 +115,18 @@ describe StatusesController do
       end
 
       it 'assigns @descendant_threads for threads with :next_status key if they are hitting the depth limit' do
-        stub_const 'StatusesController::DESCENDANTS_DEPTH_LIMIT', 1
+        stub_const 'StatusesController::DESCENDANTS_DEPTH_LIMIT', 2
         status = Fabricate(:status)
-        child = Fabricate(:status, in_reply_to_id: status.id)
+        child0 = Fabricate(:status, in_reply_to_id: status.id)
+        child1 = Fabricate(:status, in_reply_to_id: child0.id)
+        child2 = Fabricate(:status, in_reply_to_id: child0.id)
 
         get :show, params: { account_username: status.account.username, id: status.id }
 
-        expect(assigns(:descendant_threads)[0][:statuses].pluck(:id)).not_to include child.id
-        expect(assigns(:descendant_threads)[0][:next_status].id).to eq child.id
+        expect(assigns(:descendant_threads)[0][:statuses].pluck(:id)).not_to include child1.id
+        expect(assigns(:descendant_threads)[1][:statuses].pluck(:id)).not_to include child2.id
+        expect(assigns(:descendant_threads)[0][:next_status].id).to eq child1.id
+        expect(assigns(:descendant_threads)[1][:next_status].id).to eq child2.id
       end
 
       it 'returns a success' do
diff --git a/spec/controllers/stream_entries_controller_spec.rb b/spec/controllers/stream_entries_controller_spec.rb
index 534bc393dcdd80b20e1fcb72d74bb268ff7e3fe7..eb7fdf9d7823d284c21ccfde3b9ad4248ba280dc 100644
--- a/spec/controllers/stream_entries_controller_spec.rb
+++ b/spec/controllers/stream_entries_controller_spec.rb
@@ -4,7 +4,7 @@ RSpec.describe StreamEntriesController, type: :controller do
   render_views
 
   shared_examples 'before_action' do |route|
-    context 'when account is not suspended anbd stream_entry is available' do
+    context 'when account is not suspended and stream_entry is available' do
       it 'assigns instance variables' do
         status = Fabricate(:status)
 
diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb
index 33ccaed61c427d182f6f0b5682d33508c8042ca2..69def90cf7d2672e48c01eba6385649e5836d5c0 100644
--- a/spec/controllers/tags_controller_spec.rb
+++ b/spec/controllers/tags_controller_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe TagsController, type: :controller do
 
       it 'renders application layout' do
         get :show, params: { id: 'test', max_id: late.id }
-        expect(response).to render_template layout: 'application'
+        expect(response).to render_template layout: 'public'
       end
     end
 
diff --git a/spec/fabricators/account_fabricator.rb b/spec/fabricators/account_fabricator.rb
index 7aa983f821f15cb4a85c9e171ef3002e40b7a1af..e092e6c0993d4a0e98f1b3d335e512e59dc92090 100644
--- a/spec/fabricators/account_fabricator.rb
+++ b/spec/fabricators/account_fabricator.rb
@@ -6,5 +6,5 @@ Fabricator(:account) do
   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}
+  private_key         { private_key }
 end
diff --git a/spec/fabricators/account_pin_fabricator.rb b/spec/fabricators/account_pin_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c0f8b8afbb6b3abea08a0a1a6ad8bfa512108c92
--- /dev/null
+++ b/spec/fabricators/account_pin_fabricator.rb
@@ -0,0 +1,4 @@
+Fabricator(:account_pin) do
+  account        nil
+  target_account nil
+end
diff --git a/spec/fabricators/account_stat_fabricator.rb b/spec/fabricators/account_stat_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2b06b4790920deeecec58dfd0add1109bac82259
--- /dev/null
+++ b/spec/fabricators/account_stat_fabricator.rb
@@ -0,0 +1,6 @@
+Fabricator(:account_stat) do
+  account         nil
+  statuses_count  ""
+  following_count ""
+  followers_count ""
+end
diff --git a/spec/fabricators/account_tag_stat_fabricator.rb b/spec/fabricators/account_tag_stat_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9edb550beca213fb04b16e8b539d2459fa74ee4d
--- /dev/null
+++ b/spec/fabricators/account_tag_stat_fabricator.rb
@@ -0,0 +1,3 @@
+Fabricator(:account_tag_stat) do
+  accounts_count ""
+end
diff --git a/spec/fabricators/account_warning_fabricator.rb b/spec/fabricators/account_warning_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..db161d4464d5ae058b198dc75fb14f233d5a97d3
--- /dev/null
+++ b/spec/fabricators/account_warning_fabricator.rb
@@ -0,0 +1,5 @@
+Fabricator(:account_warning) do
+  account        nil
+  target_account nil
+  text           "MyText"
+end
diff --git a/spec/fabricators/account_warning_preset_fabricator.rb b/spec/fabricators/account_warning_preset_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6c0b87e7cd4831e12fbd1d16aa30bc709cb48c41
--- /dev/null
+++ b/spec/fabricators/account_warning_preset_fabricator.rb
@@ -0,0 +1,3 @@
+Fabricator(:account_warning_preset) do
+  text "MyText"
+end
diff --git a/spec/fabricators/conversation_account_fabricator.rb b/spec/fabricators/conversation_account_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f57ffd53594f9ca6da3f072f93d8f92d1578ec42
--- /dev/null
+++ b/spec/fabricators/conversation_account_fabricator.rb
@@ -0,0 +1,6 @@
+Fabricator(:conversation_account) do
+  account                 nil
+  conversation            nil
+  participant_account_ids ""
+  last_status             nil
+end
diff --git a/spec/fabricators/list_fabricator.rb b/spec/fabricators/list_fabricator.rb
index 2a61b317b8c7b281e9aa6584cf52a62c08b503d2..c3db690fa4a3c7a926c046abcf0804f04ad0249f 100644
--- a/spec/fabricators/list_fabricator.rb
+++ b/spec/fabricators/list_fabricator.rb
@@ -1,4 +1,4 @@
 Fabricator(:list) do
   account
-  title   "MyString"
+  title "MyString"
 end
diff --git a/spec/fabricators/relay_fabricator.rb b/spec/fabricators/relay_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..488913f772ea1ed0d913682b8ec784f75f5b6574
--- /dev/null
+++ b/spec/fabricators/relay_fabricator.rb
@@ -0,0 +1,4 @@
+Fabricator(:relay) do
+  inbox_url "https://example.com/inbox"
+  state :idle
+end
diff --git a/spec/fabricators/scheduled_status_fabricator.rb b/spec/fabricators/scheduled_status_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..52384d13787c8d88257bfca8590e6e4fed7d48f3
--- /dev/null
+++ b/spec/fabricators/scheduled_status_fabricator.rb
@@ -0,0 +1,4 @@
+Fabricator(:scheduled_status) do
+  account
+  scheduled_at { 20.hours.from_now }
+end
diff --git a/spec/fabricators/site_upload_fabricator.rb b/spec/fabricators/site_upload_fabricator.rb
index 8f4e43ac9baad7f28b8cfeb8aa21e69b22e234e6..4a171486f67029d59e1503e63a3163118abfa713 100644
--- a/spec/fabricators/site_upload_fabricator.rb
+++ b/spec/fabricators/site_upload_fabricator.rb
@@ -1,3 +1,2 @@
 Fabricator(:site_upload) do
-
 end
diff --git a/spec/fabricators/status_stat_fabricator.rb b/spec/fabricators/status_stat_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9c67fd404aea5d55c8d7fb03cd5a257e2b5e8e49
--- /dev/null
+++ b/spec/fabricators/status_stat_fabricator.rb
@@ -0,0 +1,6 @@
+Fabricator(:status_stat) do
+  status_id        nil
+  replies_count    ""
+  reblogs_count    ""
+  favourites_count ""
+end
diff --git a/spec/fabricators/user_fabricator.rb b/spec/fabricators/user_fabricator.rb
index cf51fe81d0e6da68cc972c2eadb788bdc957fc67..8f59565016dcdc5e8c42f04eb3d713a467c90b7d 100644
--- a/spec/fabricators/user_fabricator.rb
+++ b/spec/fabricators/user_fabricator.rb
@@ -2,5 +2,6 @@ Fabricator(:user) do
   account
   email        { sequence(:email) { |i| "#{i}#{Faker::Internet.email}" } }
   password     "123456789"
-  confirmed_at { Time.now }
+  confirmed_at { Time.zone.now }
+  agreement    true
 end
diff --git a/spec/features/log_in_spec.rb b/spec/features/log_in_spec.rb
index ed626d880ebf1a569cc5049a3ed336094e35a59e..53a1f9b126daa13f11bf7347890667163fc8e19d 100644
--- a/spec/features/log_in_spec.rb
+++ b/spec/features/log_in_spec.rb
@@ -3,7 +3,7 @@ require "rails_helper"
 feature "Log in" do
   given(:email)        { "test@examle.com" }
   given(:password)     { "password" }
-  given(:confirmed_at) { Time.now }
+  given(:confirmed_at) { Time.zone.now }
 
   background do
     Fabricate(:user, email: email, password: password, confirmed_at: confirmed_at)
diff --git a/spec/fixtures/files/4096x4097.png b/spec/fixtures/files/4096x4097.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1110cc2df0a299b47e9ad088ea61ccfd428cddb
Binary files /dev/null and b/spec/fixtures/files/4096x4097.png differ
diff --git a/spec/fixtures/requests/oembed_json_empty.html b/spec/fixtures/requests/oembed_json_empty.html
new file mode 100644
index 0000000000000000000000000000000000000000..4b02413aac333bf63e2ed4d33cf56ea54c01d184
--- /dev/null
+++ b/spec/fixtures/requests/oembed_json_empty.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <link href='https://host.test/empty_provider.json' rel='alternate' type='application/json+oembed'>
+  </head>
+  <body></body>
+</html>
diff --git a/spec/fixtures/requests/windows-1251.txt b/spec/fixtures/requests/windows-1251.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f573e28b24904f43fb6198e4d4f854449298a9dc
--- /dev/null
+++ b/spec/fixtures/requests/windows-1251.txt
@@ -0,0 +1,17 @@
+HTTP/1.1 200 OK
+server: nginx
+date: Wed, 12 Dec 2018 13:14:03 GMT
+content-type: text/html
+content-length: 190
+accept-ranges: bytes
+
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
+  <title>ñýìïë òåêñò</title>
+</head>
+<body>
+  <p>ñýìïë òåêñò</p>
+</body>
+</html>
diff --git a/spec/helpers/admin/account_moderation_notes_helper_spec.rb b/spec/helpers/admin/account_moderation_notes_helper_spec.rb
index 01b60c85162a44a3b0206318084a17c5ad0002b9..c07f6c4b886b37492c52b8ec0376ccc7ec380949 100644
--- a/spec/helpers/admin/account_moderation_notes_helper_spec.rb
+++ b/spec/helpers/admin/account_moderation_notes_helper_spec.rb
@@ -1,15 +1,55 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 
-# Specs in this file have access to a helper object that includes
-# the Admin::AccountModerationNotesHelper. For example:
-#
-# describe Admin::AccountModerationNotesHelper do
-#   describe "string concat" do
-#     it "concats two strings with spaces" do
-#       expect(helper.concat_strings("this","that")).to eq("this that")
-#     end
-#   end
-# end
 RSpec.describe Admin::AccountModerationNotesHelper, type: :helper do
-  pending "add some examples to (or delete) #{__FILE__}"
+  include StreamEntriesHelper
+
+  describe '#admin_account_link_to' do
+    context 'account is nil' do
+      let(:account) { nil }
+
+      it 'returns nil' do
+        expect(helper.admin_account_link_to(account)).to be_nil
+      end
+    end
+
+    context 'with account' do
+      let(:account) { Fabricate(:account) }
+
+      it 'calls #link_to' do
+        expect(helper).to receive(:link_to).with(
+          admin_account_path(account.id),
+          class: name_tag_classes(account),
+          title: account.acct
+        )
+
+        helper.admin_account_link_to(account)
+      end
+    end
+  end
+
+  describe '#admin_account_inline_link_to' do
+    context 'account is nil' do
+      let(:account) { nil }
+
+      it 'returns nil' do
+        expect(helper.admin_account_inline_link_to(account)).to be_nil
+      end
+    end
+
+    context 'with account' do
+      let(:account) { Fabricate(:account) }
+
+      it 'calls #link_to' do
+        expect(helper).to receive(:link_to).with(
+          admin_account_path(account.id),
+          class: name_tag_classes(account, true),
+          title: account.acct
+        )
+
+        helper.admin_account_inline_link_to(account)
+      end
+    end
+  end
 end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index ac54f1f703036a296a198f598374fa0a22f765b7..61780b46b929ef26ad2cb1625e41b5b85104f9ef 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -9,6 +9,14 @@ describe ApplicationHelper do
       expect(result).to eq "active"
     end
 
+    it 'returns active when on a current page' do
+      allow(helper).to receive(:current_page?).with('/foo').and_return(false)
+      allow(helper).to receive(:current_page?).with('/test').and_return(true)
+
+      result = helper.active_nav_class('/foo', '/test')
+      expect(result).to eq "active"
+    end
+
     it 'returns empty string when not on current page' do
       allow(helper).to receive(:current_page?).and_return(false)
 
@@ -17,7 +25,7 @@ describe ApplicationHelper do
     end
   end
 
-  describe 'add_rtl_body_class' do
+  describe 'locale_direction' do
     around do |example|
       current_locale = I18n.locale
       example.run
@@ -26,22 +34,22 @@ describe ApplicationHelper do
 
     it 'adds rtl body class if locale is Arabic' do
       I18n.locale = :ar
-      expect(helper.add_rtl_body_class('other classes')).to eq 'other classes rtl'
+      expect(helper.locale_direction).to eq 'rtl'
     end
 
     it 'adds rtl body class if locale is Farsi' do
       I18n.locale = :fa
-      expect(helper.add_rtl_body_class('other classes')).to eq 'other classes rtl'
+      expect(helper.locale_direction).to eq 'rtl'
     end
 
     it 'adds rtl if locale is Hebrew' do
       I18n.locale = :he
-      expect(helper.add_rtl_body_class('other classes')).to eq 'other classes rtl'
+      expect(helper.locale_direction).to eq 'rtl'
     end
 
     it 'does not add rtl if locale is Thai' do
       I18n.locale = :th
-      expect(helper.add_rtl_body_class('other classes')).to eq 'other classes'
+      expect(helper.locale_direction).to_not eq 'rtl'
     end
   end
 
diff --git a/spec/helpers/jsonld_helper_spec.rb b/spec/helpers/jsonld_helper_spec.rb
index a5ab249c236dbb63521ff18f6111058e2a9ba048..883a88b14df1f3ba15c01b2f0bee86e25623bc1d 100644
--- a/spec/helpers/jsonld_helper_spec.rb
+++ b/spec/helpers/jsonld_helper_spec.rb
@@ -22,11 +22,35 @@ describe JsonLdHelper do
   end
 
   describe '#first_of_value' do
-    pending
+    context 'value.is_a?(Array)' do
+      it 'returns value.first' do
+        value = ['a']
+        expect(helper.first_of_value(value)).to be 'a'
+      end
+    end
+
+    context '!value.is_a?(Array)' do
+      it 'returns value' do
+        value = 'a'
+        expect(helper.first_of_value(value)).to be 'a'
+      end
+    end
   end
 
   describe '#supported_context?' do
-    pending
+    context "!json.nil? && equals_or_includes?(json['@context'], ActivityPub::TagManager::CONTEXT)" do
+      it 'returns true' do
+        json = { '@context' => ActivityPub::TagManager::CONTEXT }.as_json
+        expect(helper.supported_context?(json)).to be true
+      end
+    end
+
+    context 'else' do
+      it 'returns false' do
+        json = nil
+        expect(helper.supported_context?(json)).to be false
+      end
+    end
   end
 
   describe '#fetch_resource' do
diff --git a/spec/helpers/stream_entries_helper_spec.rb b/spec/helpers/stream_entries_helper_spec.rb
index 1de6691ba1547f6731d7a8db82a187bb9b6c9d68..845b9974ea1b5ce7446f7869443fbb3343f96227 100644
--- a/spec/helpers/stream_entries_helper_spec.rb
+++ b/spec/helpers/stream_entries_helper_spec.rb
@@ -58,13 +58,14 @@ RSpec.describe StreamEntriesHelper, type: :helper do
       expect(acct).to eq '@user@foreign_server.com'
     end
 
-    it 'is the shortname for non embedded local accounts' do
+    it 'is fully qualified for non embedded local accounts' do
+      allow(Rails.configuration.x).to receive(:local_domain).and_return('local_domain')
       set_not_embedded_view
       account = Account.new(domain: nil, username: 'user')
 
       acct = helper.acct(account)
 
-      expect(acct).to eq '@user'
+      expect(acct).to eq '@user@local_domain'
     end
   end
 
diff --git a/spec/lib/activitypub/activity/accept_spec.rb b/spec/lib/activitypub/activity/accept_spec.rb
index 6503c83e37a33e97ab61f69850bad19e5d23d476..883bab6ac92c95306a949d6ee8010199cb535ea4 100644
--- a/spec/lib/activitypub/activity/accept_spec.rb
+++ b/spec/lib/activitypub/activity/accept_spec.rb
@@ -35,4 +35,30 @@ RSpec.describe ActivityPub::Activity::Accept do
       expect(recipient.requested?(sender)).to be false
     end
   end
+
+  context 'given a relay' do
+    let!(:relay) { Fabricate(:relay, state: :pending, follow_activity_id: 'https://abc-123/456') }
+
+    let(:json) do
+      {
+        '@context': 'https://www.w3.org/ns/activitystreams',
+        id: 'foo',
+        type: 'Accept',
+        actor: ActivityPub::TagManager.instance.uri_for(sender),
+        object: {
+          id: 'https://abc-123/456',
+          type: 'Follow',
+          actor: ActivityPub::TagManager.instance.uri_for(recipient),
+          object: ActivityPub::TagManager.instance.uri_for(sender),
+        },
+      }.with_indifferent_access
+    end
+
+    subject { described_class.new(json, sender) }
+
+    it 'marks the relay as accepted' do
+      subject.perform
+      expect(relay.reload.accepted?).to be true
+    end
+  end
 end
diff --git a/spec/lib/activitypub/activity/block_spec.rb b/spec/lib/activitypub/activity/block_spec.rb
index 23c8cc31cf799e49d402009fa3e84a0694d9dc20..94d37356dd14c23a98436a65f00161689d8d6554 100644
--- a/spec/lib/activitypub/activity/block_spec.rb
+++ b/spec/lib/activitypub/activity/block_spec.rb
@@ -14,15 +14,72 @@ RSpec.describe ActivityPub::Activity::Block do
     }.with_indifferent_access
   end
 
-  describe '#perform' do
-    subject { described_class.new(json, sender) }
+  context 'when the recipient does not follow the sender' do
+    describe '#perform' do
+      subject { described_class.new(json, sender) }
+
+      before do
+        subject.perform
+      end
+
+      it 'creates a block from sender to recipient' do
+        expect(sender.blocking?(recipient)).to be true
+      end
+    end
+  end
+
+  context 'when the recipient follows the sender' do
+    before do
+      recipient.follow!(sender)
+    end
+
+    describe '#perform' do
+      subject { described_class.new(json, sender) }
+
+      before do
+        subject.perform
+      end
+
+      it 'creates a block from sender to recipient' do
+        expect(sender.blocking?(recipient)).to be true
+      end
+
+      it 'ensures recipient is not following sender' do
+        expect(recipient.following?(sender)).to be false
+      end
+    end
+  end
+
+  context 'when a matching undo has been received first' do
+    let(:undo_json) do
+      {
+        '@context': 'https://www.w3.org/ns/activitystreams',
+        id: 'bar',
+        type: 'Undo',
+        actor: ActivityPub::TagManager.instance.uri_for(sender),
+        object: json,
+      }.with_indifferent_access
+    end
 
     before do
-      subject.perform
+      recipient.follow!(sender)
+      ActivityPub::Activity::Undo.new(undo_json, sender).perform
     end
 
-    it 'creates a block from sender to recipient' do
-      expect(sender.blocking?(recipient)).to be true
+    describe '#perform' do
+      subject { described_class.new(json, sender) }
+
+      before do
+        subject.perform
+      end
+
+      it 'does not create a block from sender to recipient' do
+        expect(sender.blocking?(recipient)).to be false
+      end
+
+      it 'ensures recipient is not following sender' do
+        expect(recipient.following?(sender)).to be false
+      end
     end
   end
 end
diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb
index 62b9db8c24d251526902f1a9d7c948e52218c1f0..cd20b7c7cb006982ee1247dd099938c436a3c5eb 100644
--- a/spec/lib/activitypub/activity/create_spec.rb
+++ b/spec/lib/activitypub/activity/create_spec.rb
@@ -105,6 +105,31 @@ RSpec.describe ActivityPub::Activity::Create do
       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) }
 
@@ -114,6 +139,10 @@ RSpec.describe ActivityPub::Activity::Create do
           type: 'Note',
           content: 'Lorem ipsum',
           to: ActivityPub::TagManager.instance.uri_for(recipient),
+          tag: {
+            type: 'Mention',
+            href: ActivityPub::TagManager.instance.uri_for(recipient),
+          },
         }
       end
 
diff --git a/spec/lib/activitypub/activity/move_spec.rb b/spec/lib/activitypub/activity/move_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3574f273a904ff4dcc2d5635ee16c7e90a243017
--- /dev/null
+++ b/spec/lib/activitypub/activity/move_spec.rb
@@ -0,0 +1,52 @@
+require 'rails_helper'
+
+RSpec.describe ActivityPub::Activity::Move do
+  let(:follower)    { Fabricate(:account) }
+  let(:old_account) { Fabricate(:account) }
+  let(:new_account) { Fabricate(:account) }
+
+  before do
+    follower.follow!(old_account)
+
+    old_account.update!(uri: 'https://example.org/alice', domain: 'example.org', protocol: :activitypub, inbox_url: 'https://example.org/inbox')
+    new_account.update!(uri: 'https://example.com/alice', domain: 'example.com', protocol: :activitypub, inbox_url: 'https://example.com/inbox', also_known_as: [old_account.uri])
+
+    stub_request(:post, 'https://example.org/inbox').to_return(status: 200)
+    stub_request(:post, 'https://example.com/inbox').to_return(status: 200)
+
+    service_stub = double
+    allow(ActivityPub::FetchRemoteAccountService).to receive(:new).and_return(service_stub)
+    allow(service_stub).to receive(:call).and_return(new_account)
+  end
+
+  let(:json) do
+    {
+      '@context': 'https://www.w3.org/ns/activitystreams',
+      id: 'foo',
+      type: 'Move',
+      actor: old_account.uri,
+      object: old_account.uri,
+      target: new_account.uri,
+    }.with_indifferent_access
+  end
+
+  describe '#perform' do
+    subject { described_class.new(json, old_account) }
+
+    before do
+      subject.perform
+    end
+
+    it 'sets moved account on old account' do
+      expect(old_account.reload.moved_to_account_id).to eq new_account.id
+    end
+
+    it 'makes followers unfollow old account' do
+      expect(follower.following?(old_account)).to be false
+    end
+
+    it 'makes followers follow-request the new account' do
+      expect(follower.requested?(new_account)).to be true
+    end
+  end
+end
diff --git a/spec/lib/activitypub/activity/reject_spec.rb b/spec/lib/activitypub/activity/reject_spec.rb
index 7fd95bcc64836e6d7e7d9daee09380c9bbbbd824..e7205df8dd6dcb30bfd18c304ef1fecdc4dd3917 100644
--- a/spec/lib/activitypub/activity/reject_spec.rb
+++ b/spec/lib/activitypub/activity/reject_spec.rb
@@ -35,4 +35,30 @@ RSpec.describe ActivityPub::Activity::Reject do
       expect(recipient.requested?(sender)).to be false
     end
   end
+
+  context 'given a relay' do
+    let!(:relay) { Fabricate(:relay, state: :pending, follow_activity_id: 'https://abc-123/456') }
+
+    let(:json) do
+      {
+        '@context': 'https://www.w3.org/ns/activitystreams',
+        id: 'foo',
+        type: 'Reject',
+        actor: ActivityPub::TagManager.instance.uri_for(sender),
+        object: {
+          id: 'https://abc-123/456',
+          type: 'Follow',
+          actor: ActivityPub::TagManager.instance.uri_for(recipient),
+          object: ActivityPub::TagManager.instance.uri_for(sender),
+        },
+      }.with_indifferent_access
+    end
+
+    subject { described_class.new(json, sender) }
+
+    it 'marks the relay as rejected' do
+      subject.perform
+      expect(relay.reload.rejected?).to be true
+    end
+  end
 end
diff --git a/spec/lib/activitypub/activity/undo_spec.rb b/spec/lib/activitypub/activity/undo_spec.rb
index e01c5e03e70554e5f2d6572d877168ebe63413f2..9545e1f46af6b98ba924ad53b5e84f2e2cc7ebdb 100644
--- a/spec/lib/activitypub/activity/undo_spec.rb
+++ b/spec/lib/activitypub/activity/undo_spec.rb
@@ -52,6 +52,32 @@ RSpec.describe ActivityPub::Activity::Undo do
       end
     end
 
+    context 'with Accept' do
+      let(:recipient) { Fabricate(:account) }
+      let(:object_json) do
+        {
+          id: 'bar',
+          type: 'Accept',
+          actor: ActivityPub::TagManager.instance.uri_for(sender),
+          object: 'follow-to-revoke',
+        }
+      end
+
+      before do
+        recipient.follow!(sender, uri: 'follow-to-revoke')
+      end
+
+      it 'deletes follow from recipient to sender' do
+        subject.perform
+        expect(recipient.following?(sender)).to be false
+      end
+
+      it 'creates a follow request from recipient to sender' do
+        subject.perform
+        expect(recipient.requested?(sender)).to be true
+      end
+    end
+
     context 'with Block' do
       let(:recipient) { Fabricate(:account) }
 
diff --git a/spec/lib/feed_manager_spec.rb b/spec/lib/feed_manager_spec.rb
index 7535e144d7d935ed8a530e67724a8ec3352509a3..c506cd87f171db43229ea4e2dec1fee8e0d1b6d9 100644
--- a/spec/lib/feed_manager_spec.rb
+++ b/spec/lib/feed_manager_spec.rb
@@ -108,14 +108,14 @@ RSpec.describe FeedManager do
 
       it 'returns false for status by followee mentioning another account' do
         bob.follow!(alice)
-        status = PostStatusService.new.call(alice, 'Hey @jeff')
+        status = PostStatusService.new.call(alice, text: 'Hey @jeff')
         expect(FeedManager.instance.filter?(:home, status, bob.id)).to be false
       end
 
       it 'returns true for status by followee mentioning blocked account' do
         bob.block!(jeff)
         bob.follow!(alice)
-        status = PostStatusService.new.call(alice, 'Hey @jeff')
+        status = PostStatusService.new.call(alice, text: 'Hey @jeff')
         expect(FeedManager.instance.filter?(:home, status, bob.id)).to be true
       end
 
@@ -155,7 +155,7 @@ RSpec.describe FeedManager do
     context 'for mentions feed' do
       it 'returns true for status that mentions blocked account' do
         bob.block!(jeff)
-        status = PostStatusService.new.call(alice, 'Hey @jeff')
+        status = PostStatusService.new.call(alice, text: 'Hey @jeff')
         expect(FeedManager.instance.filter?(:mentions, status, bob.id)).to be true
       end
 
@@ -393,7 +393,7 @@ RSpec.describe FeedManager do
     end
 
     it 'sends push updates' do
-      status  = Fabricate(:status)
+      status = Fabricate(:status)
 
       FeedManager.instance.push_to_home(receiver, status)
 
diff --git a/spec/lib/formatter_spec.rb b/spec/lib/formatter_spec.rb
index b8683e720bfe45acc83895221b2011ec4f9dbc14..0c1efe7c3cc763799e0e5c77ab1ef820f7d2d3b1 100644
--- a/spec/lib/formatter_spec.rb
+++ b/spec/lib/formatter_spec.rb
@@ -5,26 +5,26 @@ RSpec.describe Formatter do
   let(:remote_account) { Fabricate(:account, domain: 'remote.test', username: 'bob', url: 'https://remote.test/') }
 
   shared_examples 'encode and link URLs' do
-    context 'matches a stand-alone medium URL' do
+    context 'given a stand-alone medium URL' do
       let(:text) { 'https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4' }
 
-      it 'has valid URL' do
+      it 'matches the full URL' do
         is_expected.to include 'href="https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4"'
       end
     end
 
-    context 'matches a stand-alone google URL' do
+    context 'given a stand-alone google URL' do
       let(:text) { 'http://google.com' }
 
-      it 'has valid URL' do
+      it 'matches the full URL' do
         is_expected.to include 'href="http://google.com"'
       end
     end
 
-    context 'matches a stand-alone IDN URL' do
+    context 'given a stand-alone IDN URL' do
       let(:text) { 'https://nic.みんな/' }
 
-      it 'has valid URL' do
+      it 'matches the full URL' do
         is_expected.to include 'href="https://nic.みんな/"'
       end
 
@@ -33,148 +33,170 @@ RSpec.describe Formatter do
       end
     end
 
-    context 'matches a URL without trailing period' do
+    context 'given a URL with a trailing period' do
       let(:text) { 'http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona. ' }
 
-      it 'has valid URL' do
+      it 'matches the full URL but not the period' do
         is_expected.to include 'href="http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona"'
       end
     end
 
-    context 'matches a URL without closing paranthesis' do
+    context 'given a URL enclosed with parentheses' do
       let(:text) { '(http://google.com/)' }
 
-      it 'has valid URL' do
+      it 'matches the full URL but not the parentheses' do
         is_expected.to include 'href="http://google.com/"'
       end
     end
 
-    context 'matches a URL without exclamation point' do
+    context 'given a URL with a trailing exclamation point' do
       let(:text) { 'http://www.google.com!' }
 
-      it 'has valid URL' do
+      it 'matches the full URL but not the exclamation point' do
         is_expected.to include 'href="http://www.google.com"'
       end
     end
 
-    context 'matches a URL without single quote' do
+    context 'given a URL with a trailing single quote' do
       let(:text) { "http://www.google.com'" }
 
-      it 'has valid URL' do
+      it 'matches the full URL but not the single quote' do
         is_expected.to include 'href="http://www.google.com"'
       end
     end
 
-    context 'matches a URL without angle brackets' do
+    context 'given a URL with a trailing angle bracket' do
       let(:text) { 'http://www.google.com>' }
 
-      it 'has valid URL' do
+      it 'matches the full URL but not the angle bracket' do
         is_expected.to include 'href="http://www.google.com"'
       end
     end
 
-    context 'matches a URL with a query string' do
+    context 'given a URL with a query string' do
       let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' }
 
-      it 'has valid URL' do
+      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 'matches a URL with parenthesis in it' do
+    context 'given a URL with parentheses in it' do
       let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' }
 
-      it 'has valid URL' do
+      it 'matches the full URL' do
         is_expected.to include 'href="https://en.wikipedia.org/wiki/Diaspora_(software)"'
       end
     end
 
-    context 'matches a URL with Japanese path string' do
+    context 'given a URL with Japanese path string' do
       let(:text) { 'https://ja.wikipedia.org/wiki/日本' }
 
-      it 'has valid URL' do
+      it 'matches the full URL' do
         is_expected.to include 'href="https://ja.wikipedia.org/wiki/日本"'
       end
     end
 
-    context 'matches a URL with Korean path string' do
+    context 'given a URL with Korean path string' do
       let(:text) { 'https://ko.wikipedia.org/wiki/대한민국' }
 
-      it 'has valid URL' do
+      it 'matches the full URL' do
         is_expected.to include 'href="https://ko.wikipedia.org/wiki/대한민국"'
       end
     end
 
-    context 'matches a URL with Simplified Chinese path string' do
+    context 'given a URL with Simplified Chinese path string' do
       let(:text) { 'https://baike.baidu.com/item/中华人民共和国' }
 
-      it 'has valid URL' do
+      it 'matches the full URL' do
         is_expected.to include 'href="https://baike.baidu.com/item/中华人民共和国"'
       end
     end
 
-    context 'matches a URL with Traditional Chinese path string' do
+    context 'given a URL with Traditional Chinese path string' do
       let(:text) { 'https://zh.wikipedia.org/wiki/臺灣' }
 
-      it 'has valid URL' do
+      it 'matches the full URL' do
         is_expected.to include 'href="https://zh.wikipedia.org/wiki/臺灣"'
       end
     end
 
-    context 'contains unsafe URL (XSS attack, visible part)' do
+    context 'given a URL containing unsafe code (XSS attack, visible part)' do
       let(:text) { %q{http://example.com/b<del>b</del>} }
 
-      it 'has escaped HTML' do
+      it 'escapes the HTML in the URL' do
         is_expected.to include '&lt;del&gt;b&lt;/del&gt;'
       end
     end
 
-    context 'contains unsafe URL (XSS attack, invisible part)' 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 'has escaped HTML' do
+      it 'escapes the HTML in the URL' do
         is_expected.to include '&lt;script&gt;alert(&quot;Hello&quot;)&lt;/script&gt;'
       end
     end
 
-    context 'contains HTML (script tag)' do
+    context 'given text containing HTML code (script tag)' do
       let(:text) { '<script>alert("Hello")</script>' }
 
-      it 'has escaped HTML' do
+      it 'escapes the HTML' do
         is_expected.to include '<p>&lt;script&gt;alert(&quot;Hello&quot;)&lt;/script&gt;</p>'
       end
     end
 
-    context 'contains HTML (XSS attack)' do
+    context 'given text containing HTML (XSS attack)' do
       let(:text) { %q{<img src="javascript:alert('XSS');">} }
 
-      it 'has escaped HTML' do
+      it 'escapes the HTML' do
         is_expected.to include '<p>&lt;img src=&quot;javascript:alert(&apos;XSS&apos;);&quot;&gt;</p>'
       end
     end
 
-    context 'contains invalid URL' do
+    context 'given an invalid URL' do
       let(:text) { 'http://www\.google\.com' }
 
-      it 'has raw URL' do
+      it 'outputs the raw URL' do
         is_expected.to eq '<p>http://www\.google\.com</p>'
       end
     end
 
-    context 'contains a hashtag' do
+    context 'given text containing a hashtag' do
       let(:text)  { '#hashtag' }
 
-      it 'has a link' do
+      it 'creates a hashtag link' do
         is_expected.to include '/tags/hashtag" class="mention hashtag" rel="tag">#<span>hashtag</span></a>'
       end
     end
   end
 
+  describe '#format_spoiler' do
+    subject { Formatter.instance.format_spoiler(status) }
+
+    context 'given a post containing plain text' do
+      let(:status) { Fabricate(:status, text: 'text', spoiler_text: 'Secret!', uri: nil) }
+
+      it 'Returns the spoiler text' do
+        is_expected.to eq 'Secret!'
+      end
+    end
+
+    context 'given a post with an emoji shortcode at the start' do
+      let!(:emoji) { Fabricate(:custom_emoji) }
+      let(:status) { Fabricate(:status, text: 'text', spoiler_text: ':coolcat: Secret!', uri: nil) }
+      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:"/)
+      end
+    end
+  end
+
   describe '#format' do
     subject { Formatter.instance.format(status) }
 
-    context 'with local status' do
-      context 'with reblog' do
+    context 'given a post with local status' do
+      context 'given a reblogged post' do
         let(:reblog) { Fabricate(:status, account: local_account, text: 'Hello world', uri: nil) }
         let(:status) { Fabricate(:status, reblog: reblog) }
 
@@ -183,34 +205,34 @@ RSpec.describe Formatter do
         end
       end
 
-      context 'contains plain text' do
-        let(:status)  { Fabricate(:status, text: 'text', uri: nil) }
+      context 'given a post containing plain text' do
+        let(:status) { Fabricate(:status, text: 'text', uri: nil) }
 
-        it 'paragraphizes' do
+        it 'paragraphizes the text' do
           is_expected.to eq '<p>text</p>'
         end
       end
 
-      context 'contains line feeds' do
-        let(:status)  { Fabricate(:status, text: "line\nfeed", uri: nil) }
+      context 'given a post containing line feeds' do
+        let(:status) { Fabricate(:status, text: "line\nfeed", uri: nil) }
 
         it 'removes line feeds' do
           is_expected.not_to include "\n"
         end
       end
 
-      context 'contains linkable mentions' do
+      context 'given a post containing linkable mentions' do
         let(:status) { Fabricate(:status, mentions: [ Fabricate(:mention, account: local_account) ], text: '@alice') }
 
-        it 'links' do
+        it 'creates a mention link' do
           is_expected.to include '<a href="https://cb6e6126.ngrok.io/@alice" class="u-url mention">@<span>alice</span></a></span>'
         end
       end
 
-      context 'contains unlinkable mentions' do
+      context 'given a post containing unlinkable mentions' do
         let(:status) { Fabricate(:status, text: '@alice', uri: nil) }
 
-        it 'does not link' do
+        it 'does not create a mention link' do
           is_expected.to include '@alice'
         end
       end
@@ -224,29 +246,29 @@ RSpec.describe Formatter do
         include_examples 'encode and link URLs'
       end
 
-      context 'with custom_emojify option' do
+      context 'given a post with custom_emojify option' do
         let!(:emoji) { Fabricate(:custom_emoji) }
         let(:status) { Fabricate(:status, account: local_account, text: text) }
 
         subject { Formatter.instance.format(status, custom_emojify: true) }
 
-        context 'with emoji at the start' do
+        context 'given a post with an emoji shortcode at the start' do
           let(:text) { ':coolcat: Beep boop' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
 
-        context 'with emoji in the middle' do
+        context 'given a post with an emoji shortcode in the middle' do
           let(:text) { 'Beep :coolcat: boop' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
 
-        context 'with concatenated emoji' do
+        context 'given a post with concatenated emoji shortcodes' do
           let(:text) { ':coolcat::coolcat:' }
 
           it 'does not touch the shortcodes' do
@@ -254,46 +276,46 @@ RSpec.describe Formatter do
           end
         end
 
-        context 'with emoji at the end' do
+        context 'given a post with an emoji shortcode at the end' do
           let(:text) { 'Beep boop :coolcat:' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/boop <img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
       end
     end
 
-    context 'with remote status' do
+    context 'given a post with remote status' do
       let(:status) { Fabricate(:status, account: remote_account, text: 'Beep boop') }
 
-      it 'reformats' do
+      it 'reformats the post' do
         is_expected.to eq 'Beep boop'
       end
 
-      context 'with custom_emojify option' do
+      context 'given a post with custom_emojify option' do
         let!(:emoji) { Fabricate(:custom_emoji, domain: remote_account.domain) }
         let(:status) { Fabricate(:status, account: remote_account, text: text) }
 
         subject { Formatter.instance.format(status, custom_emojify: true) }
 
-        context 'with emoji at the start' do
+        context 'given a post with an emoji shortcode at the start' do
           let(:text) { '<p>:coolcat: Beep boop<br />' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
 
-        context 'with emoji in the middle' do
+        context 'given a post with an emoji shortcode in the middle' do
           let(:text) { '<p>Beep :coolcat: boop</p>' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
 
-        context 'with concatenated emoji' do
+        context 'given a post with concatenated emoji' do
           let(:text) { '<p>:coolcat::coolcat:</p>' }
 
           it 'does not touch the shortcodes' do
@@ -301,10 +323,10 @@ RSpec.describe Formatter do
           end
         end
 
-        context 'with emoji at the end' do
+        context 'given a post with an emoji shortcode at the end' do
           let(:text) { '<p>Beep boop<br />:coolcat:</p>' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/<br><img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
@@ -315,26 +337,26 @@ RSpec.describe Formatter do
   describe '#reformat' do
     subject { Formatter.instance.reformat(text) }
 
-    context 'contains plain text' do
+    context 'given a post containing plain text' do
       let(:text) { 'Beep boop' }
 
-      it 'contains plain text' do
+      it 'keeps the plain text' do
         is_expected.to include 'Beep boop'
       end
     end
 
-    context 'contains scripts' do
+    context 'given a post containing script tags' do
       let(:text) { '<script>alert("Hello")</script>' }
 
-      it 'strips scripts' do
+      it 'strips the scripts' do
         is_expected.to_not include '<script>alert("Hello")</script>'
       end
     end
 
-    context 'contains malicious classes' do
+    context 'given a post containing malicious classes' do
       let(:text) { '<span class="mention	status__content__spoiler-link">Show more</span>' }
 
-      it 'strips malicious classes' do
+      it 'strips the malicious classes' do
         is_expected.to_not include 'status__content__spoiler-link'
       end
     end
@@ -343,16 +365,16 @@ RSpec.describe Formatter do
   describe '#plaintext' do
     subject { Formatter.instance.plaintext(status) }
 
-    context 'with local status' do
-      let(:status)  { Fabricate(:status, text: '<p>a text by a nerd who uses an HTML tag in text</p>', uri: nil) }
+    context 'given a post with local status' do
+      let(:status) { Fabricate(:status, text: '<p>a text by a nerd who uses an HTML tag in text</p>', uri: nil) }
 
-      it 'returns raw text' do
+      it 'returns the raw text' do
         is_expected.to eq '<p>a text by a nerd who uses an HTML tag in text</p>'
       end
     end
 
-    context 'with remote status' do
-      let(:status)  { Fabricate(:status, account: remote_account, text: '<script>alert("Hello")</script>') }
+    context 'given a post with remote status' do
+      let(:status) { Fabricate(:status, account: remote_account, text: '<script>alert("Hello")</script>') }
 
       it 'returns tag-stripped text' do
         is_expected.to eq ''
@@ -363,60 +385,60 @@ RSpec.describe Formatter do
   describe '#simplified_format' do
     subject { Formatter.instance.simplified_format(account) }
 
-    context 'with local status' do
+    context 'given a post with local status' do
       let(:account) { Fabricate(:account, domain: nil, note: text) }
 
-      context 'contains linkable mentions for local accounts' do
+      context 'given a post containing linkable mentions for local accounts' do
         let(:text) { '@alice' }
 
         before { local_account }
 
-        it 'links' do
+        it 'creates a mention link' do
           is_expected.to eq '<p><span class="h-card"><a href="https://cb6e6126.ngrok.io/@alice" class="u-url mention">@<span>alice</span></a></span></p>'
         end
       end
 
-      context 'contains linkable mentions for remote accounts' do
+      context 'given a post containing linkable mentions for remote accounts' do
         let(:text) { '@bob@remote.test' }
 
         before { remote_account }
 
-        it 'links' do
+        it 'creates a mention link' do
           is_expected.to eq '<p><span class="h-card"><a href="https://remote.test/" class="u-url mention">@<span>bob</span></a></span></p>'
         end
       end
 
-      context 'contains unlinkable mentions' do
+      context 'given a post containing unlinkable mentions' do
         let(:text) { '@alice' }
 
-        it 'returns raw mention texts' do
+        it 'does not create a mention link' do
           is_expected.to eq '<p>@alice</p>'
         end
       end
 
-      context 'with custom_emojify option' do
+      context 'given a post with custom_emojify option' do
         let!(:emoji) { Fabricate(:custom_emoji) }
 
         before { account.note = text }
         subject { Formatter.instance.simplified_format(account, custom_emojify: true) }
 
-        context 'with emoji at the start' do
+        context 'given a post with an emoji shortcode at the start' do
           let(:text) { ':coolcat: Beep boop' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
 
-        context 'with emoji in the middle' do
+        context 'given a post with an emoji shortcode in the middle' do
           let(:text) { 'Beep :coolcat: boop' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
 
-        context 'with concatenated emoji' do
+        context 'given a post with concatenated emoji shortcodes' do
           let(:text) { ':coolcat::coolcat:' }
 
           it 'does not touch the shortcodes' do
@@ -424,10 +446,10 @@ RSpec.describe Formatter do
           end
         end
 
-        context 'with emoji at the end' do
+        context 'given a post with an emoji shortcode at the end' do
           let(:text) { 'Beep boop :coolcat:' }
 
-          it 'converts shortcode to image tag' do
+          it 'converts the shortcode to an image tag' do
             is_expected.to match(/boop <img draggable="false" class="emojione" alt=":coolcat:"/)
           end
         end
@@ -436,7 +458,7 @@ RSpec.describe Formatter do
       include_examples 'encode and link URLs'
     end
 
-    context 'with remote status' do
+    context 'given a post with remote status' do
       let(:text) { '<script>alert("Hello")</script>' }
       let(:account) { Fabricate(:account, domain: 'remote', note: text) }
 
@@ -451,7 +473,7 @@ RSpec.describe Formatter do
 
         subject { Formatter.instance.simplified_format(remote_account, custom_emojify: true) }
 
-        context 'with emoji at the start' do
+        context 'given a post with an emoji shortcode at the start' do
           let(:text) { '<p>:coolcat: Beep boop<br />' }
 
           it 'converts shortcode to image tag' do
@@ -459,7 +481,7 @@ RSpec.describe Formatter do
           end
         end
 
-        context 'with emoji in the middle' do
+        context 'given a post with an emoji shortcode in the middle' do
           let(:text) { '<p>Beep :coolcat: boop</p>' }
 
           it 'converts shortcode to image tag' do
@@ -467,7 +489,7 @@ RSpec.describe Formatter do
           end
         end
 
-        context 'with concatenated emoji' do
+        context 'given a post with concatenated emoji shortcodes' do
           let(:text) { '<p>:coolcat::coolcat:</p>' }
 
           it 'does not touch the shortcodes' do
@@ -475,7 +497,7 @@ RSpec.describe Formatter do
           end
         end
 
-        context 'with emoji at the end' do
+        context 'given a post with an emoji shortcode at the end' do
           let(:text) { '<p>Beep boop<br />:coolcat:</p>' }
 
           it 'converts shortcode to image tag' do
@@ -492,7 +514,7 @@ RSpec.describe Formatter do
     subject { Formatter.instance.sanitize(html, Sanitize::Config::MASTODON_STRICT) }
 
     it 'sanitizes' do
-      is_expected.to eq 'alert("Hello")'
+      is_expected.to eq ''
     end
   end
 end
diff --git a/spec/lib/language_detector_spec.rb b/spec/lib/language_detector_spec.rb
index d1702651156b1374d962b139512b91c53b02af09..0fa2a59eff9150830de9bfa4f61f6e722d2ccfd4 100644
--- a/spec/lib/language_detector_spec.rb
+++ b/spec/lib/language_detector_spec.rb
@@ -42,6 +42,7 @@ describe LanguageDetector do
 
   describe 'detect' do
     let(:account_without_user_locale) { Fabricate(:user, locale: nil).account }
+    let(:account_remote) { Fabricate(:account, domain: 'joinmastodon.org') }
 
     it 'detects english language for basic strings' do
       strings = [
@@ -57,7 +58,7 @@ describe LanguageDetector do
     end
 
     it 'detects spanish language' do
-      string = 'Obtener un Hola y bienvenidos a Mastodon'
+      string = 'Obtener un Hola y bienvenidos a Mastodon. Obtener un Hola y bienvenidos a Mastodon. Obtener un Hola y bienvenidos a Mastodon. Obtener un Hola y bienvenidos a Mastodon'
       result = described_class.instance.detect(string, account_without_user_locale)
 
       expect(result).to eq :es
@@ -86,11 +87,11 @@ describe LanguageDetector do
           account = double(user_locale: 'fr')
           result  = described_class.instance.detect('', account)
 
-          expect(result).to eq :fr
+          expect(result).to eq nil
         end
 
         it 'uses nil when account is present but has no locale' do
-          result  = described_class.instance.detect('', account_without_user_locale)
+          result = described_class.instance.detect('', account_without_user_locale)
 
           expect(result).to eq nil
         end
@@ -104,6 +105,15 @@ describe LanguageDetector do
         end
       end
 
+      describe 'remote user' do
+        it 'nil for foreign user when language is not present' do
+          string = '안녕하세요'
+          result = described_class.instance.detect(string, account_remote)
+
+          expect(result).to eq nil
+        end
+      end
+
       describe 'with a non-`en` default locale' do
         around(:each) do |example|
           before = I18n.default_locale
diff --git a/spec/lib/ostatus/atom_serializer_spec.rb b/spec/lib/ostatus/atom_serializer_spec.rb
index 0bd22880e0c346b363fd0669b3e46a010c71be31..891871c1c7fabbabd3ed938348951e87bdd55316 100644
--- a/spec/lib/ostatus/atom_serializer_spec.rb
+++ b/spec/lib/ostatus/atom_serializer_spec.rb
@@ -728,9 +728,9 @@ RSpec.describe OStatus::AtomSerializer do
     it 'appends id element with unique tag' do
       block = Fabricate(:block)
 
-      time_before = Time.now
+      time_before = Time.zone.now
       block_salmon = OStatus::AtomSerializer.new.block_salmon(block)
-      time_after = Time.now
+      time_after = Time.zone.now
 
       expect(block_salmon.id.text).to(
         eq(OStatus::TagManager.instance.unique_tag(time_before.utc, block.id, 'Block'))
@@ -815,9 +815,9 @@ RSpec.describe OStatus::AtomSerializer do
     it 'appends id element with unique tag' do
       block = Fabricate(:block)
 
-      time_before = Time.now
+      time_before = Time.zone.now
       unblock_salmon = OStatus::AtomSerializer.new.unblock_salmon(block)
-      time_after = Time.now
+      time_after = Time.zone.now
 
       expect(unblock_salmon.id.text).to(
         eq(OStatus::TagManager.instance.unique_tag(time_before.utc, block.id, 'Block'))
@@ -880,7 +880,7 @@ RSpec.describe OStatus::AtomSerializer do
 
       ProcessInteractionService.new.call(envelope, block.target_account)
 
-      expect{ block.reload }.to raise_error ActiveRecord::RecordNotFound
+      expect { block.reload }.to raise_error ActiveRecord::RecordNotFound
     end
   end
 
@@ -994,9 +994,9 @@ RSpec.describe OStatus::AtomSerializer do
     it 'appends id element with unique tag' do
       favourite = Fabricate(:favourite)
 
-      time_before = Time.now
+      time_before = Time.zone.now
       unfavourite_salmon = OStatus::AtomSerializer.new.unfavourite_salmon(favourite)
-      time_after = Time.now
+      time_after = Time.zone.now
 
       expect(unfavourite_salmon.id.text).to(
         eq(OStatus::TagManager.instance.unique_tag(time_before.utc, favourite.id, 'Favourite'))
@@ -1179,9 +1179,9 @@ RSpec.describe OStatus::AtomSerializer do
       follow = Fabricate(:follow)
       follow.destroy!
 
-      time_before = Time.now
+      time_before = Time.zone.now
       unfollow_salmon = OStatus::AtomSerializer.new.unfollow_salmon(follow)
-      time_after = Time.now
+      time_after = Time.zone.now
 
       expect(unfollow_salmon.id.text).to(
         eq(OStatus::TagManager.instance.unique_tag(time_before.utc, follow.id, 'Follow'))
@@ -1327,9 +1327,9 @@ RSpec.describe OStatus::AtomSerializer do
     it 'appends id element with unique tag' do
       follow_request = Fabricate(:follow_request)
 
-      time_before = Time.now
+      time_before = Time.zone.now
       authorize_follow_request_salmon = OStatus::AtomSerializer.new.authorize_follow_request_salmon(follow_request)
-      time_after = Time.now
+      time_after = Time.zone.now
 
       expect(authorize_follow_request_salmon.id.text).to(
         eq(OStatus::TagManager.instance.unique_tag(time_before.utc, follow_request.id, 'FollowRequest'))
@@ -1396,9 +1396,9 @@ RSpec.describe OStatus::AtomSerializer do
     it 'appends id element with unique tag' do
       follow_request = Fabricate(:follow_request)
 
-      time_before = Time.now
+      time_before = Time.zone.now
       reject_follow_request_salmon = OStatus::AtomSerializer.new.reject_follow_request_salmon(follow_request)
-      time_after = Time.now
+      time_after = Time.zone.now
 
       expect(reject_follow_request_salmon.id.text).to(
         eq(OStatus::TagManager.instance.unique_tag(time_before.utc, follow_request.id, 'FollowRequest'))
diff --git a/spec/lib/request_spec.rb b/spec/lib/request_spec.rb
index 939ac006ae1531870bcdfda47309cc4dd99e4d67..2d300f18d6c71494d97fe6b42a9ca811e83ee055 100644
--- a/spec/lib/request_spec.rb
+++ b/spec/lib/request_spec.rb
@@ -48,9 +48,11 @@ describe Request do
       end
 
       it 'executes a HTTP request when the first address is private' do
-        allow(Addrinfo).to receive(:foreach).with('example.com', nil, nil, :SOCK_STREAM)
-                                            .and_yield(Addrinfo.new(["AF_INET", 0, "example.com", "0.0.0.0"], :PF_INET, :SOCK_STREAM))
-                                            .and_yield(Addrinfo.new(["AF_INET6", 0, "example.com", "2001:4860:4860::8844"], :PF_INET6, :SOCK_STREAM))
+        resolver = double
+
+        allow(resolver).to receive(:getaddresses).with('example.com').and_return(%w(0.0.0.0 2001:4860:4860::8844))
+        allow(resolver).to receive(:timeouts=).and_return(nil)
+        allow(Resolv::DNS).to receive(:open).and_yield(resolver)
 
         expect { |block| subject.perform &block }.to yield_control
         expect(a_request(:get, 'http://example.com')).to have_been_made.once
@@ -81,10 +83,13 @@ describe Request do
       end
 
       it 'raises Mastodon::ValidationError' do
-        allow(Addrinfo).to receive(:foreach).with('example.com', nil, nil, :SOCK_STREAM)
-                                            .and_yield(Addrinfo.new(["AF_INET", 0, "example.com", "0.0.0.0"], :PF_INET, :SOCK_STREAM))
-                                            .and_yield(Addrinfo.new(["AF_INET6", 0, "example.com", "2001:db8::face"], :PF_INET6, :SOCK_STREAM))
-        expect{ subject.perform }.to raise_error Mastodon::ValidationError
+        resolver = double
+
+        allow(resolver).to receive(:getaddresses).with('example.com').and_return(%w(0.0.0.0 2001:db8::face))
+        allow(resolver).to receive(:timeouts=).and_return(nil)
+        allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+
+        expect { subject.perform }.to raise_error Mastodon::ValidationError
       end
     end
   end
diff --git a/spec/mailers/admin_mailer_spec.rb b/spec/mailers/admin_mailer_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4a8ef7b5eaee23ffa602ad4bf63517f36307fbbb
--- /dev/null
+++ b/spec/mailers/admin_mailer_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe AdminMailer, type: :mailer do
+  describe '.new_report' do
+    let(:sender)    { Fabricate(:account, username: 'John', user: Fabricate(:user)) }
+    let(:recipient) { Fabricate(:account, username: 'Mike', user: Fabricate(:user, locale: :en)) }
+    let(:report)    { Fabricate(:report, account: sender, target_account: recipient) }
+    let(:mail)      { described_class.new_report(recipient, report) }
+
+    it 'renders the headers' do
+      expect(mail.subject).to eq("New report for cb6e6126.ngrok.io (##{report.id})")
+      expect(mail.to).to eq [recipient.user_email]
+      expect(mail.from).to eq ['notifications@localhost']
+    end
+
+    it 'renders the body' do
+      expect(mail.body.encoded).to eq("Mike,\r\n\r\nJohn has reported Mike\r\n\r\nView: https://cb6e6126.ngrok.io/admin/reports/#{report.id}\r\n")
+    end
+  end
+end
diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb
index 1be01e8baa16f8b924fbb8d96700df3d5d9c93e5..38916b54f1d34d7be41d1eadf8ef2f2994b1b573 100644
--- a/spec/mailers/notification_mailer_spec.rb
+++ b/spec/mailers/notification_mailer_spec.rb
@@ -126,19 +126,7 @@ RSpec.describe NotificationMailer, type: :mailer do
       end
     end
 
-    it 'includes activities since the date specified by :since option' do
-      receiver.update!(last_emailed_at: '2000-02-01T00:00:00Z', current_sign_in_at: '2000-03-01T00:00:00Z')
-      mail = NotificationMailer.digest(receiver.account, since: Time.parse('2000-01-01T00:00:00Z'))
-      expect(mail.body.encoded).to include 'Jan 01, 2000, 00:00'
-    end
-
-    it 'includes activities since the receiver was last emailed if :since option is unavailable' do
-      receiver.update!(last_emailed_at: '2000-02-01T00:00:00Z', current_sign_in_at: '2000-03-01T00:00:00Z')
-      mail = NotificationMailer.digest(receiver.account)
-      expect(mail.body.encoded).to include 'Feb 01, 2000, 00:00'
-    end
-
-    it 'includes activities since the receiver last signed in if :since option and the last emailed date are unavailable' do
+    it 'includes activities since the receiver last signed in' do
       receiver.update!(last_emailed_at: nil, current_sign_in_at: '2000-03-01T00:00:00Z')
       mail = NotificationMailer.digest(receiver.account)
       expect(mail.body.encoded).to include 'Mar 01, 2000, 00:00'
diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb
index d9cdb9264a6507815f7515ee02709cd1f5fa77c5..53c8364944579c9ef74eca4fa4ce9ddca9206597 100644
--- a/spec/mailers/previews/user_mailer_preview.rb
+++ b/spec/mailers/previews/user_mailer_preview.rb
@@ -39,4 +39,9 @@ class UserMailerPreview < ActionMailer::Preview
   def backup_ready
     UserMailer.backup_ready(User.first, Backup.first)
   end
+
+  # Preview this email at http://localhost:3000/rails/mailers/user_mailer/warning
+  def warning
+    UserMailer.warning(User.first, AccountWarning.new(text: '', action: :silence))
+  end
 end
diff --git a/spec/models/account_conversation_spec.rb b/spec/models/account_conversation_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..70a76281ef8185b8babe1fc5aa44a485849e3c15
--- /dev/null
+++ b/spec/models/account_conversation_spec.rb
@@ -0,0 +1,72 @@
+require 'rails_helper'
+
+RSpec.describe AccountConversation, type: :model do
+  let!(:alice) { Fabricate(:account, username: 'alice') }
+  let!(:bob)   { Fabricate(:account, username: 'bob') }
+  let!(:mark)  { Fabricate(:account, username: 'mark') }
+
+  describe '.add_status' do
+    it 'creates new record when no others exist' do
+      status = Fabricate(:status, account: alice, visibility: :direct)
+      status.mentions.create(account: bob)
+
+      conversation = AccountConversation.add_status(alice, status)
+
+      expect(conversation.participant_accounts).to include(bob)
+      expect(conversation.last_status).to eq status
+      expect(conversation.status_ids).to eq [status.id]
+    end
+
+    it 'appends to old record when there is a match' do
+      last_status  = Fabricate(:status, account: alice, visibility: :direct)
+      conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id])
+
+      status = Fabricate(:status, account: bob, visibility: :direct, thread: last_status)
+      status.mentions.create(account: alice)
+
+      new_conversation = AccountConversation.add_status(alice, status)
+
+      expect(new_conversation.id).to eq conversation.id
+      expect(new_conversation.participant_accounts).to include(bob)
+      expect(new_conversation.last_status).to eq status
+      expect(new_conversation.status_ids).to eq [last_status.id, status.id]
+    end
+
+    it 'creates new record when new participants are added' do
+      last_status  = Fabricate(:status, account: alice, visibility: :direct)
+      conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id])
+
+      status = Fabricate(:status, account: bob, visibility: :direct, thread: last_status)
+      status.mentions.create(account: alice)
+      status.mentions.create(account: mark)
+
+      new_conversation = AccountConversation.add_status(alice, status)
+
+      expect(new_conversation.id).to_not eq conversation.id
+      expect(new_conversation.participant_accounts).to include(bob, mark)
+      expect(new_conversation.last_status).to eq status
+      expect(new_conversation.status_ids).to eq [status.id]
+    end
+  end
+
+  describe '.remove_status' do
+    it 'updates last status to a previous value' do
+      last_status  = Fabricate(:status, account: alice, visibility: :direct)
+      status       = Fabricate(:status, account: alice, visibility: :direct)
+      conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [status.id, last_status.id])
+      last_status.mentions.create(account: bob)
+      last_status.destroy!
+      conversation.reload
+      expect(conversation.last_status).to eq status
+      expect(conversation.status_ids).to eq [status.id]
+    end
+
+    it 'removes the record if no other statuses are referenced' do
+      last_status  = Fabricate(:status, account: alice, visibility: :direct)
+      conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id])
+      last_status.mentions.create(account: bob)
+      last_status.destroy!
+      expect(AccountConversation.where(id: conversation.id).count).to eq 0
+    end
+  end
+end
diff --git a/spec/models/account_filter_spec.rb b/spec/models/account_filter_spec.rb
index 8441939c5b7438039c2c3d454c2b9b5b7150e630..176a0eeacd0ce055c8f71f664a689b2553eec8a5 100644
--- a/spec/models/account_filter_spec.rb
+++ b/spec/models/account_filter_spec.rb
@@ -2,10 +2,10 @@ require 'rails_helper'
 
 describe AccountFilter do
   describe 'with empty params' do
-    it 'defaults to alphabetic account list' do
+    it 'defaults to recent local not-suspended account list' do
       filter = described_class.new({})
 
-      expect(filter.results).to eq Account.alphabetic
+      expect(filter.results).to eq Account.local.recent.without_suspended
     end
   end
 
@@ -17,23 +17,6 @@ describe AccountFilter do
     end
   end
 
-  describe 'when an IP address is provided' do
-    it 'filters with IP when valid' do
-      filter = described_class.new(ip: '127.0.0.1')
-      allow(User).to receive(:with_recent_ip_address).and_return(User.none)
-
-      filter.results
-      expect(User).to have_received(:with_recent_ip_address).with('127.0.0.1')
-    end
-
-    it 'skips IP when invalid' do
-      filter = described_class.new(ip: '345.678.901.234')
-      expect(User).not_to receive(:with_recent_ip_address)
-
-      filter.results
-    end
-  end
-
   describe 'with valid params' do
     it 'combines filters on Account' do
       filter = described_class.new(
@@ -60,13 +43,13 @@ describe AccountFilter do
     end
 
     describe 'that call account methods' do
-      %i(local remote silenced recent suspended).each do |option|
+      %i(local remote silenced suspended).each do |option|
         it "delegates the #{option} option" do
           allow(Account).to receive(option).and_return(Account.none)
           filter = described_class.new({ option => true })
           filter.results
 
-          expect(Account).to have_received(option)
+          expect(Account).to have_received(option).at_least(1)
         end
       end
     end
diff --git a/spec/models/account_moderation_note_spec.rb b/spec/models/account_moderation_note_spec.rb
index 16983b2e3601c7e14f9277295474fb3bb2692ced..69bd5500a5be689070c96eb892d888d586b06e39 100644
--- a/spec/models/account_moderation_note_spec.rb
+++ b/spec/models/account_moderation_note_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe AccountModerationNote, type: :model do
-
 end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index 4f71935d582003bd8c66a803ad9fd2cb85cf5a99..47b22719334c5de3229e4899c546a9f76ec0e93e 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -275,7 +275,7 @@ RSpec.describe Account, type: :model do
 
     subject { Fabricate(:account) }
 
-    context 'when the status is a reblog of another status'do
+    context 'when the status is a reblog of another status' do
       let(:original_reblog) do
         author = Fabricate(:account, username: 'original_reblogger')
         Fabricate(:status, reblog: original_status, account: author)
@@ -559,7 +559,7 @@ RSpec.describe Account, type: :model do
     end
 
     context 'when is local' do
-      it 'is invalid if the username is not unique in case-insensitive comparsion among local accounts' 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')
         account_2 = Fabricate.build(:account, username: 'the_Doctor')
         account_2.valid?
@@ -618,10 +618,16 @@ RSpec.describe Account, type: :model do
         expect(account).not_to model_have_error_on_field(:username)
       end
 
-      it 'is valid even if the username doesn\'t only contains letters, numbers and underscores' do
+      it 'is valid even if the username contains hyphens' do
         account = Fabricate.build(:account, domain: 'domain', username: 'the-doctor')
         account.valid?
-        expect(account).not_to model_have_error_on_field(:username)
+        expect(account).to_not model_have_error_on_field(:username)
+      end
+
+      it 'is invalid if the username doesn\'t only contains letters, numbers, underscores and hyphens' do
+        account = Fabricate.build(:account, domain: 'domain', username: 'the doctor')
+        account.valid?
+        expect(account).to model_have_error_on_field(:username)
       end
 
       it 'is valid even if the username is longer then 30 characters' do
@@ -754,24 +760,6 @@ RSpec.describe Account, type: :model do
         expect(Account.suspended).to match_array([account_1])
       end
     end
-
-    describe 'without_followers' do
-      it 'returns a relation of accounts without followers' do
-        account_1 = Fabricate(:account)
-        account_2 = Fabricate(:account)
-        Fabricate(:follow, account: account_1, target_account: account_2)
-        expect(Account.without_followers).to match_array([account_1])
-      end
-    end
-
-    describe 'with_followers' do
-      it 'returns a relation of accounts with followers' do
-        account_1 = Fabricate(:account)
-        account_2 = Fabricate(:account)
-        Fabricate(:follow, account: account_1, target_account: account_2)
-        expect(Account.with_followers).to match_array([account_2])
-      end
-    end
   end
 
   context 'when is local' do
diff --git a/spec/models/account_stat_spec.rb b/spec/models/account_stat_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a94185109c774d8701e914b1d2fe6d4b945f8447
--- /dev/null
+++ b/spec/models/account_stat_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+
+RSpec.describe AccountStat, type: :model do
+end
diff --git a/spec/models/account_tag_stat_spec.rb b/spec/models/account_tag_stat_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6d3057f3555eb808993d763e4f26edafadc2451c
--- /dev/null
+++ b/spec/models/account_tag_stat_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe AccountTagStat, type: :model do
+  key = 'accounts_count'
+  let(:account_tag_stat) { Fabricate(:tag).account_tag_stat }
+
+  describe '#increment_count!' do
+    it 'calls #update' do
+      args = { key => account_tag_stat.public_send(key) + 1 }
+      expect(account_tag_stat).to receive(:update).with(args)
+      account_tag_stat.increment_count!(key)
+    end
+
+    it 'increments value by 1' do
+      expect do
+        account_tag_stat.increment_count!(key)
+      end.to change { account_tag_stat.accounts_count }.by(1)
+    end
+  end
+
+  describe '#decrement_count!' do
+    it 'calls #update' do
+      args = { key => [account_tag_stat.public_send(key) - 1, 0].max }
+      expect(account_tag_stat).to receive(:update).with(args)
+      account_tag_stat.decrement_count!(key)
+    end
+
+    it 'decrements value by 1' do
+      account_tag_stat.update(key => 1)
+
+      expect do
+        account_tag_stat.decrement_count!(key)
+      end.to change { account_tag_stat.accounts_count }.by(-1)
+    end
+  end
+end
diff --git a/spec/models/admin/account_action_spec.rb b/spec/models/admin/account_action_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a3db60cfc85c95585a9713b9fbe9d2c90f084477
--- /dev/null
+++ b/spec/models/admin/account_action_spec.rb
@@ -0,0 +1,131 @@
+require 'rails_helper'
+
+RSpec.describe Admin::AccountAction, type: :model do
+  let(:account_action) { described_class.new }
+
+  describe '#save!' do
+    subject              { account_action.save! }
+    let(:account)        { Fabricate(:account, user: Fabricate(:user, admin: true)) }
+    let(:target_account) { Fabricate(:account, user: Fabricate(:user)) }
+    let(:type)           { 'disable' }
+
+    before do
+      account_action.assign_attributes(
+        type:            type,
+        current_account: account,
+        target_account:  target_account
+      )
+    end
+
+    context 'type is "disable"' do
+      let(:type) { 'disable' }
+
+      it 'disable user' do
+        subject
+        expect(target_account.user).to be_disabled
+      end
+    end
+
+    context 'type is "silence"' do
+      let(:type) { 'silence' }
+
+      it 'silences account' do
+        subject
+        expect(target_account).to be_silenced
+      end
+    end
+
+    context 'type is "suspend"' do
+      let(:type) { 'suspend' }
+
+      it 'suspends account' do
+        subject
+        expect(target_account).to be_suspended
+      end
+
+      it 'queues Admin::SuspensionWorker by 1' do
+        Sidekiq::Testing.fake! do
+          expect do
+            subject
+          end.to change { Admin::SuspensionWorker.jobs.size }.by 1
+        end
+      end
+    end
+
+    it 'creates Admin::ActionLog' do
+      expect do
+        subject
+      end.to change { Admin::ActionLog.count }.by 1
+    end
+
+    it 'calls queue_email!' do
+      expect(account_action).to receive(:queue_email!)
+      subject
+    end
+
+    it 'calls process_reports!' do
+      expect(account_action).to receive(:process_reports!)
+      subject
+    end
+  end
+
+  describe '#report' do
+    subject { account_action.report }
+
+    context 'report_id.present?' do
+      before do
+        account_action.report_id = Fabricate(:report).id
+      end
+
+      it 'returns Report' do
+        expect(subject).to be_instance_of Report
+      end
+    end
+
+    context '!report_id.present?' do
+      it 'returns nil' do
+        expect(subject).to be_nil
+      end
+    end
+  end
+
+  describe '#with_report?' do
+    subject { account_action.with_report? }
+
+    context '!report.nil?' do
+      before do
+        account_action.report_id = Fabricate(:report).id
+      end
+
+      it 'returns true' do
+        expect(subject).to be true
+      end
+    end
+
+    context '!(!report.nil?)' do
+      it 'returns false' do
+        expect(subject).to be false
+      end
+    end
+  end
+
+  describe '.types_for_account' do
+    subject { described_class.types_for_account(account) }
+
+    context 'account.local?' do
+      let(:account) { Fabricate(:account, domain: nil) }
+
+      it 'returns ["none", "disable", "silence", "suspend"]' do
+        expect(subject).to eq %w(none disable silence suspend)
+      end
+    end
+
+    context '!account.local?' do
+      let(:account) { Fabricate(:account, domain: 'hoge.com') }
+
+      it 'returns ["silence", "suspend"]' do
+        expect(subject).to eq %w(silence suspend)
+      end
+    end
+  end
+end
diff --git a/spec/models/admin/action_log_spec.rb b/spec/models/admin/action_log_spec.rb
index 59206a36b3f1a3f001688b341b9666ab32b11e87..3495cc51414cb30c08ae986325f55b2707f3289e 100644
--- a/spec/models/admin/action_log_spec.rb
+++ b/spec/models/admin/action_log_spec.rb
@@ -1,5 +1,12 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 
 RSpec.describe Admin::ActionLog, type: :model do
-
+  describe '#action' do
+    it 'returns action' do
+      action_log = described_class.new(action: 'hoge')
+      expect(action_log.action).to be :hoge
+    end
+  end
 end
diff --git a/spec/models/backup_spec.rb b/spec/models/backup_spec.rb
index fabcdc845a83f228dd56ea236d3292a187c152e1..45230986d7a98f0e285b8137a6851a3358324e19 100644
--- a/spec/models/backup_spec.rb
+++ b/spec/models/backup_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe Backup, type: :model do
-
 end
diff --git a/spec/models/concerns/remotable_spec.rb b/spec/models/concerns/remotable_spec.rb
index b39233739c03ba13fe31e81f448348426c8642cf..a4289cc45e79aca0e8e251eb1b6113007a4eabeb 100644
--- a/spec/models/concerns/remotable_spec.rb
+++ b/spec/models/concerns/remotable_spec.rb
@@ -88,7 +88,18 @@ RSpec.describe Remotable do
 
       context 'parsed_url.host is empty' do
         it 'makes no request' do
-          parsed_url = double(scheme: 'https', host: double(empty?: true))
+          parsed_url = double(scheme: 'https', host: double(blank?: true))
+          allow(Addressable::URI).to receive_message_chain(:parse, :normalize)
+            .with(url).with(no_args).and_return(parsed_url)
+
+          foo.hoge_remote_url = url
+          expect(request).not_to have_been_requested
+        end
+      end
+
+      context 'parsed_url.host is nil' do
+        it 'makes no request' do
+          parsed_url = Addressable::URI.parse('https:https://example.com/path/file.png')
           allow(Addressable::URI).to receive_message_chain(:parse, :normalize)
             .with(url).with(no_args).and_return(parsed_url)
 
diff --git a/spec/models/concerns/status_threading_concern_spec.rb b/spec/models/concerns/status_threading_concern_spec.rb
index e5736a307909970a88918729b35e7a09c228fc9a..94c2d5fc2e84e95007f2e54acbabe76f2e316b92 100644
--- a/spec/models/concerns/status_threading_concern_spec.rb
+++ b/spec/models/concerns/status_threading_concern_spec.rb
@@ -118,5 +118,15 @@ describe StatusThreadingConcern do
       viewer.block_domain!('example.com')
       expect(status.descendants(4, viewer)).to_not include(reply2)
     end
+
+    it 'promotes self-replies to the top while leaving the rest in order' do
+      a = Fabricate(:status, account: alice)
+      d = Fabricate(:status, account: jeff, thread: a)
+      e = Fabricate(:status, account: bob, thread: d)
+      c = Fabricate(:status, account: alice, thread: a)
+      f = Fabricate(:status, account: bob, thread: c)
+
+      expect(a.descendants(20)).to eq [c, d, e, f]
+    end
   end
 end
diff --git a/spec/models/conversation_mute_spec.rb b/spec/models/conversation_mute_spec.rb
index b602e80c194a6de37c28a00a31251337981a092a..3fc2915d4f33fd6c0d8d1d8c7b129891fcf33dbe 100644
--- a/spec/models/conversation_mute_spec.rb
+++ b/spec/models/conversation_mute_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe ConversationMute, type: :model do
-
 end
diff --git a/spec/models/custom_emoji_filter_spec.rb b/spec/models/custom_emoji_filter_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d859f5c5f5067db3f6cdd32221dce22c51dfce3e
--- /dev/null
+++ b/spec/models/custom_emoji_filter_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe CustomEmojiFilter do
+  describe '#results' do
+    let!(:custom_emoji_0) { Fabricate(:custom_emoji, domain: 'a') }
+    let!(:custom_emoji_1) { Fabricate(:custom_emoji, domain: 'b') }
+    let!(:custom_emoji_2) { Fabricate(:custom_emoji, domain: nil, shortcode: 'hoge') }
+
+    subject { described_class.new(params).results }
+
+    context 'params have values' do
+      context 'local' do
+        let(:params) { { local: true } }
+
+        it 'returns ActiveRecord::Relation' do
+          expect(subject).to be_kind_of(ActiveRecord::Relation)
+          expect(subject).to match_array([custom_emoji_2])
+        end
+      end
+
+      context 'remote' do
+        let(:params) { { remote: true } }
+
+        it 'returns ActiveRecord::Relation' do
+          expect(subject).to be_kind_of(ActiveRecord::Relation)
+          expect(subject).to match_array([custom_emoji_0, custom_emoji_1])
+        end
+      end
+
+      context 'by_domain' do
+        let(:params) { { by_domain: 'a' } }
+
+        it 'returns ActiveRecord::Relation' do
+          expect(subject).to be_kind_of(ActiveRecord::Relation)
+          expect(subject).to match_array([custom_emoji_0])
+        end
+      end
+
+      context 'shortcode' do
+        let(:params) { { shortcode: 'hoge' } }
+
+        it 'returns ActiveRecord::Relation' do
+          expect(subject).to be_kind_of(ActiveRecord::Relation)
+          expect(subject).to match_array([custom_emoji_2])
+        end
+      end
+
+      context 'else' do
+        let(:params) { { else: 'else' } }
+
+        it 'raises RuntimeError' do
+          expect do
+            subject
+          end.to raise_error(RuntimeError, /Unknown filter: else/)
+        end
+      end
+    end
+
+    context 'params without value' do
+      let(:params) { { hoge: nil } }
+
+      it 'returns ActiveRecord::Relation' do
+        expect(subject).to be_kind_of(ActiveRecord::Relation)
+        expect(subject).to match_array([custom_emoji_0, custom_emoji_1, custom_emoji_2])
+      end
+    end
+  end
+end
diff --git a/spec/models/custom_emoji_spec.rb b/spec/models/custom_emoji_spec.rb
index 87367df5003a47b20e4b090f8822bc66a29eb28d..9de218b4fed15ffa4518d93727f8ddd70ef15e14 100644
--- a/spec/models/custom_emoji_spec.rb
+++ b/spec/models/custom_emoji_spec.rb
@@ -4,7 +4,7 @@ RSpec.describe CustomEmoji, type: :model do
   describe '#search' do
     let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: shortcode) }
 
-    subject  { described_class.search(search_term) }
+    subject { described_class.search(search_term) }
 
     context 'shortcode is exact' do
       let(:shortcode) { 'blobpats' }
@@ -75,4 +75,13 @@ RSpec.describe CustomEmoji, type: :model do
       end
     end
   end
+
+  describe 'pre_validation' do
+    let(:custom_emoji) { Fabricate(:custom_emoji, domain: 'wWw.MaStOdOn.CoM') }
+
+    it 'should downcase' do
+      custom_emoji.valid?
+      expect(custom_emoji.domain).to eq('www.mastodon.com')
+    end
+  end
 end
diff --git a/spec/models/custom_filter_spec.rb b/spec/models/custom_filter_spec.rb
index 1024542e7be5007b05207652e8525a9644a5fd0d..3943dd5f1a219aff1f541bf598aeaf540647d30f 100644
--- a/spec/models/custom_filter_spec.rb
+++ b/spec/models/custom_filter_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe CustomFilter, type: :model do
-
 end
diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb
index 6daa4614575bf570f46e7807d67dca47adc5bcd7..277dcc526498858f20a160bb391a5a27d541f6c2 100644
--- a/spec/models/export_spec.rb
+++ b/spec/models/export_spec.rb
@@ -48,17 +48,17 @@ describe Export do
   describe 'total_follows' do
     it 'returns the total number of the followed accounts' do
       target_accounts.each(&account.method(:follow!))
-      expect(Export.new(account).total_follows).to eq 2
+      expect(Export.new(account.reload).total_follows).to eq 2
     end
 
     it 'returns the total number of the blocked accounts' do
       target_accounts.each(&account.method(:block!))
-      expect(Export.new(account).total_blocks).to eq 2
+      expect(Export.new(account.reload).total_blocks).to eq 2
     end
 
     it 'returns the total number of the muted accounts' do
       target_accounts.each(&account.method(:mute!))
-      expect(Export.new(account).total_mutes).to eq 2
+      expect(Export.new(account.reload).total_mutes).to eq 2
     end
   end
 end
diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb
index 43175d8526aded12266038f046e9efe75bc82acf..0c84e5e7bfa2458455859733d850cb746e1c3bbd 100644
--- a/spec/models/follow_spec.rb
+++ b/spec/models/follow_spec.rb
@@ -23,6 +23,20 @@ RSpec.describe Follow, type: :model do
       follow.valid?
       expect(follow).to model_have_error_on_field(:target_account)
     end
+
+    it 'is invalid if account already follows too many people' do
+      alice.update(following_count: FollowLimitValidator::LIMIT)
+
+      expect(subject).to_not be_valid
+      expect(subject).to model_have_error_on_field(:base)
+    end
+
+    it 'is valid if account is only on the brink of following too many people' do
+      alice.update(following_count: FollowLimitValidator::LIMIT - 1)
+
+      expect(subject).to be_valid
+      expect(subject).to_not model_have_error_on_field(:base)
+    end
   end
 
   describe 'recent' do
@@ -37,4 +51,20 @@ RSpec.describe Follow, type: :model do
       expect(a[1]).to eq follow0
     end
   end
+
+  describe 'revoke_request!' do
+    let(:follow)         { Fabricate(:follow, account: account, target_account: target_account) }
+    let(:account)        { Fabricate(:account) }
+    let(:target_account) { Fabricate(:account) }
+
+    it 'revokes the follow relation' do
+      follow.revoke_request!
+      expect(account.following?(target_account)).to be false
+    end
+
+    it 'creates a follow request' do
+      follow.revoke_request!
+      expect(account.requested?(target_account)).to be true
+    end
+  end
 end
diff --git a/spec/models/identity_spec.rb b/spec/models/identity_spec.rb
index 53f35541022a15daf97abf51d392089659289a56..689c9b797f4f6327695af58cd2de248d51088c50 100644
--- a/spec/models/identity_spec.rb
+++ b/spec/models/identity_spec.rb
@@ -1,5 +1,16 @@
 require 'rails_helper'
 
 RSpec.describe Identity, type: :model do
-  pending "add some examples to (or delete) #{__FILE__}"
+  describe '.find_for_oauth' do
+    let(:auth) { Fabricate(:identity, user: Fabricate(:user)) }
+
+    it 'calls .find_or_create_by' do
+      expect(described_class).to receive(:find_or_create_by).with(uid: auth.uid, provider: auth.provider)
+      described_class.find_for_oauth(auth)
+    end
+
+    it 'returns an instance of Identity' do
+      expect(described_class.find_for_oauth(auth)).to be_instance_of Identity
+    end
+  end
 end
diff --git a/spec/models/list_account_spec.rb b/spec/models/list_account_spec.rb
index a132e09b0eaae6027efbbeb9c33a9e1e1c1cc7db..a0cf02efe25f5ac5afc1570cc4a5833e638a61d4 100644
--- a/spec/models/list_account_spec.rb
+++ b/spec/models/list_account_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe ListAccount, type: :model do
-
 end
diff --git a/spec/models/list_spec.rb b/spec/models/list_spec.rb
index c302482b4388e50dd60263f0fc581afe0ae97bde..b780bb1de071706d81ad19295a5a80318d629e3e 100644
--- a/spec/models/list_spec.rb
+++ b/spec/models/list_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe List, type: :model do
-
 end
diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb
index d2230b6d0ff01f144394500685260b3c2758d0f1..266cd492039ec6a3ab1305fc7d7f463766584756 100644
--- a/spec/models/media_attachment_spec.rb
+++ b/spec/models/media_attachment_spec.rb
@@ -129,9 +129,9 @@ RSpec.describe MediaAttachment, type: :model do
       expect(media.file.meta["original"]["width"]).to eq 600
       expect(media.file.meta["original"]["height"]).to eq 400
       expect(media.file.meta["original"]["aspect"]).to eq 1.5
-      expect(media.file.meta["small"]["width"]).to eq 400
-      expect(media.file.meta["small"]["height"]).to eq 267
-      expect(media.file.meta["small"]["aspect"]).to eq 400.0/267
+      expect(media.file.meta["small"]["width"]).to eq 490
+      expect(media.file.meta["small"]["height"]).to eq 327
+      expect(media.file.meta["small"]["aspect"]).to eq 490.0 / 327
     end
   end
 
diff --git a/spec/models/mute_spec.rb b/spec/models/mute_spec.rb
index 83ba793b2b1bd717d919f7c77aae838cf054c896..38a87bdf4a772c3ec4081785e9a3d9d39bd698a9 100644
--- a/spec/models/mute_spec.rb
+++ b/spec/models/mute_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe Mute, type: :model do
-
 end
diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb
index c781f2a294b5847330e7da5b4ba37723e55afd78..59c582cde0d26075f77cf20ac0fe29c0eb71cc4d 100644
--- a/spec/models/notification_spec.rb
+++ b/spec/models/notification_spec.rb
@@ -1,10 +1,6 @@
 require 'rails_helper'
 
 RSpec.describe Notification, type: :model do
-  describe '#from_account' do
-    pending
-  end
-
   describe '#target_status' do
     let(:notification) { Fabricate(:notification, activity: activity) }
     let(:status)       { Fabricate(:status) }
@@ -101,7 +97,7 @@ RSpec.describe Notification, type: :model do
       before do
         allow(accounts_with_ids).to receive(:[]).with(stale_account1.id).and_return(account1)
         allow(accounts_with_ids).to receive(:[]).with(stale_account2.id).and_return(account2)
-        allow(Account).to receive_message_chain(:where, :map, :to_h).and_return(accounts_with_ids)
+        allow(Account).to receive_message_chain(:where, :includes, :each_with_object).and_return(accounts_with_ids)
       end
 
       let(:cached_items) do
diff --git a/spec/models/preview_card_spec.rb b/spec/models/preview_card_spec.rb
index 14ef23923cb7468ffaf9c1e3edcc5e89813ef1a7..45233d1d4f9f3ef9b22da2380e18978a270b4cdf 100644
--- a/spec/models/preview_card_spec.rb
+++ b/spec/models/preview_card_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe PreviewCard, type: :model do
-
 end
diff --git a/spec/models/relay_spec.rb b/spec/models/relay_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..12dc0f20f6e615fd49991ffe97f440ee423b45dc
--- /dev/null
+++ b/spec/models/relay_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+
+RSpec.describe Relay, type: :model do
+end
diff --git a/spec/models/remote_follow_spec.rb b/spec/models/remote_follow_spec.rb
index 72c580f9f1cc35e777bb2568c73f469970dbded2..ed2667b28aad82eb4242543284033974ff57b1c5 100644
--- a/spec/models/remote_follow_spec.rb
+++ b/spec/models/remote_follow_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe RemoteFollow do
     subject { remote_follow.valid? }
 
     context 'attrs with acct' do
-      let(:attrs) { { acct: 'gargron@quitter.no' }}
+      let(:attrs) { { acct: 'gargron@quitter.no' } }
 
       it do
         is_expected.to be true
@@ -42,7 +42,7 @@ RSpec.describe RemoteFollow do
     end
 
     context 'attrs without acct' do
-      let(:attrs) { { } }
+      let(:attrs) { {} }
 
       it do
         is_expected.to be false
diff --git a/spec/models/scheduled_status_spec.rb b/spec/models/scheduled_status_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f8c9d8b81f6c4ad35c4b57ca177a01f48b75caa5
--- /dev/null
+++ b/spec/models/scheduled_status_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+
+RSpec.describe ScheduledStatus, type: :model do
+end
diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb
index b3e475d99cfe9acdeb400e56caa958db28150dbd..e8cf18af905978176b6730d915d7f5317c40ad04 100644
--- a/spec/models/status_spec.rb
+++ b/spec/models/status_spec.rb
@@ -154,7 +154,7 @@ RSpec.describe Status, type: :model do
 
   describe '#target' do
     it 'returns nil if the status is self-contained' do
-     expect(subject.target).to be_nil
+      expect(subject.target).to be_nil
     end
 
     it 'returns nil if the status is a reply' do
@@ -182,6 +182,27 @@ RSpec.describe Status, type: :model do
       reblog.destroy
       expect(subject.reblogs_count).to eq 0
     end
+
+    it 'does not fail when original is deleted before reblog' do
+      reblog = Fabricate(:status, account: bob, reblog: subject)
+      expect(subject.reblogs_count).to eq 1
+      expect { subject.destroy }.to_not raise_error
+      expect(Status.find_by(id: reblog.id)).to be_nil
+    end
+  end
+
+  describe '#replies_count' do
+    it 'is the number of replies' do
+      reply = Fabricate(:status, account: bob, thread: subject)
+      expect(subject.replies_count).to eq 1
+    end
+
+    it 'is decremented when reply is removed' do
+      reply = Fabricate(:status, account: bob, thread: subject)
+      expect(subject.replies_count).to eq 1
+      reply.destroy
+      expect(subject.replies_count).to eq 0
+    end
   end
 
   describe '#favourites_count' do
@@ -552,17 +573,6 @@ RSpec.describe Status, type: :model do
           expect(results).to include(es_status)
         end
       end
-
-      context 'where that account is silenced' do
-        it 'includes statuses from other accounts that are silenced' do
-          @account.update(silenced: true)
-          other_silenced_account = Fabricate(:account, silenced: true)
-          other_status = Fabricate(:status, account: other_silenced_account)
-
-          results = Status.as_public_timeline(@account)
-          expect(results).to include(other_status)
-        end
-      end
     end
   end
 
diff --git a/spec/models/status_stat_spec.rb b/spec/models/status_stat_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..af1a6f288be8492f5ec07ca42b6263f23fe7ae07
--- /dev/null
+++ b/spec/models/status_stat_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+
+RSpec.describe StatusStat, type: :model do
+end
diff --git a/spec/models/subscription_spec.rb b/spec/models/subscription_spec.rb
index 84096e6ae80f7ecf68e00f56cf97fa49faf55cad..b83979d13799f4d3134d2a0dfd2f62658d6daada 100644
--- a/spec/models/subscription_spec.rb
+++ b/spec/models/subscription_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe Subscription, type: :model do
   end
 
   describe 'lease_seconds' do
-    it 'returns the time remaing until expiration' do
+    it 'returns the time remaining until expiration' do
       datetime = 1.day.from_now
       subscription = Subscription.new(expires_at: datetime)
       travel_to(datetime - 12.hours) do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 93a6c26fb25abfbd7709125092984d4fc1aff401..856254ce4b6acd1908b5ace92e3e0681c0145b94 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -67,7 +67,7 @@ RSpec.describe User, type: :model do
     describe 'confirmed' do
       it 'returns an array of users who are confirmed' do
         user_1 = Fabricate(:user, confirmed_at: nil)
-        user_2 = Fabricate(:user, confirmed_at: Time.now)
+        user_2 = Fabricate(:user, confirmed_at: Time.zone.now)
         expect(User.confirmed).to match_array([user_2])
       end
     end
@@ -89,18 +89,6 @@ RSpec.describe User, type: :model do
         expect(User.matches_email('specified')).to match_array([specified])
       end
     end
-
-    describe 'with_recent_ip_address' do
-      it 'returns a relation of users who is, or was at last time, online with the given IP address' do
-        specifieds = [
-          Fabricate(:user, current_sign_in_ip: '0.0.0.42', last_sign_in_ip: '0.0.0.0'),
-          Fabricate(:user, current_sign_in_ip: nil, last_sign_in_ip: '0.0.0.42')
-        ]
-        Fabricate(:user, current_sign_in_ip: '0.0.0.0', last_sign_in_ip: '0.0.0.0')
-
-        expect(User.with_recent_ip_address('0.0.0.42')).to match_array(specifieds)
-      end
-    end
   end
 
   let(:account) { Fabricate(:account, username: 'alice') }
@@ -118,19 +106,19 @@ RSpec.describe User, type: :model do
     end
 
     it 'should allow a non-blacklisted user to be created' do
-      user = User.new(email: 'foo@example.com', account: account, password: password)
+      user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true)
 
       expect(user.valid?).to be_truthy
     end
 
     it 'should not allow a blacklisted user to be created' do
-      user = User.new(email: 'foo@mvrht.com', account: account, password: password)
+      user = User.new(email: 'foo@mvrht.com', account: account, password: password, agreement: true)
 
       expect(user.valid?).to be_falsey
     end
 
     it 'should not allow a subdomain blacklisted user to be created' do
-      user = User.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password)
+      user = User.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password, agreement: true)
 
       expect(user.valid?).to be_falsey
     end
@@ -222,17 +210,17 @@ RSpec.describe User, type: :model do
     end
 
     it 'should not allow a user to be created unless they are whitelisted' do
-      user = User.new(email: 'foo@example.com', account: account, password: password)
+      user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true)
       expect(user.valid?).to be_falsey
     end
 
     it 'should allow a user to be created if they are whitelisted' do
-      user = User.new(email: 'foo@mastodon.space', account: account, password: password)
+      user = User.new(email: 'foo@mastodon.space', account: account, password: password, agreement: true)
       expect(user.valid?).to be_truthy
     end
 
     it 'should not allow a user with a whitelisted top domain as subdomain in their email address to be created' do
-      user = User.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password)
+      user = User.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password, agreement: true)
       expect(user.valid?).to be_falsey
     end
 
@@ -254,7 +242,7 @@ RSpec.describe User, type: :model do
 
   it_behaves_like 'Settings-extended' do
     def create!
-      User.create!(account: Fabricate(:account), email: 'foo@mastodon.space', password: 'abcd1234' )
+      User.create!(account: Fabricate(:account), email: 'foo@mastodon.space', password: 'abcd1234', agreement: true)
     end
 
     def fabricate
@@ -512,7 +500,7 @@ RSpec.describe User, type: :model do
       context 'when user is confirmed' do
         let(:confirmed_at) { Time.zone.now }
 
-        it { is_expected.to be false }
+        it { is_expected.to be true }
       end
 
       context 'when user is not confirmed' do
diff --git a/spec/models/web/setting_spec.rb b/spec/models/web/setting_spec.rb
index 90e7695aa77d1f49a3200bd9061d445f85bcb30c..6657d4030f4dbeedb8b8e1f441c7b57660ff51ff 100644
--- a/spec/models/web/setting_spec.rb
+++ b/spec/models/web/setting_spec.rb
@@ -1,5 +1,4 @@
 require 'rails_helper'
 
 RSpec.describe Web::Setting, type: :model do
-
 end
diff --git a/spec/policies/account_moderation_note_policy_spec.rb b/spec/policies/account_moderation_note_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bb7af94e45564c1952c53e329c9a1032667cf92a
--- /dev/null
+++ b/spec/policies/account_moderation_note_policy_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe AccountModerationNotePolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :create? do
+    context 'staff' do
+      it 'grants to create' do
+        expect(subject).to permit(admin, AccountModerationNotePolicy)
+      end
+    end
+
+    context 'not staff' do
+      it 'denies to create' do
+        expect(subject).to_not permit(john, AccountModerationNotePolicy)
+      end
+    end
+  end
+
+  permissions :destroy? do
+    let(:account_moderation_note) do
+      Fabricate(:account_moderation_note,
+                account: john,
+                target_account: Fabricate(:account))
+    end
+
+    context 'admin' do
+      it 'grants to destroy' do
+        expect(subject).to permit(admin, AccountModerationNotePolicy)
+      end
+    end
+
+    context 'owner' do
+      it 'grants to destroy' do
+        expect(subject).to permit(john, account_moderation_note)
+      end
+    end
+
+    context 'neither admin nor owner' do
+      let(:kevin) { Fabricate(:user).account }
+
+      it 'denies to destroy' do
+        expect(subject).to_not permit(kevin, account_moderation_note)
+      end
+    end
+  end
+end
diff --git a/spec/policies/account_policy_spec.rb b/spec/policies/account_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6648b0888bf6e830379875285f7699de23e4aeaf
--- /dev/null
+++ b/spec/policies/account_policy_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe AccountPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index?, :show?, :unsuspend?, :unsilence?, :remove_avatar?, :remove_header? do
+    context 'staff' do
+      it 'permits' do
+        expect(subject).to permit(admin)
+      end
+    end
+
+    context 'not staff' do
+      it 'denies' do
+        expect(subject).to_not permit(john)
+      end
+    end
+  end
+
+  permissions :redownload?, :subscribe?, :unsubscribe? do
+    context 'admin' do
+      it 'permits' do
+        expect(subject).to permit(admin)
+      end
+    end
+
+    context 'not admin' do
+      it 'denies' do
+        expect(subject).to_not permit(john)
+      end
+    end
+  end
+
+  permissions :suspend?, :silence? do
+    let(:staff) { Fabricate(:user, admin: true).account }
+
+    context 'staff' do
+      context 'record is staff' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, staff)
+        end
+      end
+
+      context 'record is not staff' do
+        it 'permits' do
+          expect(subject).to permit(admin, john)
+        end
+      end
+    end
+
+    context 'not staff' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Account)
+      end
+    end
+  end
+
+  permissions :memorialize? do
+    let(:other_admin) { Fabricate(:user, admin: true).account }
+
+    context 'admin' do
+      context 'record is admin' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, other_admin)
+        end
+      end
+
+      context 'record is not admin' do
+        it 'permits' do
+          expect(subject).to permit(admin, john)
+        end
+      end
+    end
+
+    context 'not admin' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Account)
+      end
+    end
+  end
+end
diff --git a/spec/policies/backup_policy_spec.rb b/spec/policies/backup_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..80407e12f850de0ab7f99e9d28b8232daa80db9f
--- /dev/null
+++ b/spec/policies/backup_policy_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe BackupPolicy do
+  let(:subject) { described_class }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :create? do
+    context 'not user_signed_in?' do
+      it 'denies' do
+        expect(subject).to_not permit(nil, Backup)
+      end
+    end
+
+    context 'user_signed_in?' do
+      context 'no backups' do
+        it 'permits' do
+          expect(subject).to permit(john, Backup)
+        end
+      end
+
+      context 'backups are too old' do
+        it 'permits' do
+          travel(-8.days) do
+            Fabricate(:backup, user: john.user)
+          end
+
+          expect(subject).to permit(john, Backup)
+        end
+      end
+
+      context 'backups are newer' do
+        it 'denies' do
+          travel(-3.days) do
+            Fabricate(:backup, user: john.user)
+          end
+
+          expect(subject).to_not permit(john, Backup)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/policies/custom_emoji_policy_spec.rb b/spec/policies/custom_emoji_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8def88212fb41afbaf73bf083733f19521c8c463
--- /dev/null
+++ b/spec/policies/custom_emoji_policy_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe CustomEmojiPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index?, :enable?, :disable? do
+    context 'staff' do
+      it 'permits' do
+        expect(subject).to permit(admin, CustomEmoji)
+      end
+    end
+
+    context 'not staff' do
+      it 'denies' do
+        expect(subject).to_not permit(john, CustomEmoji)
+      end
+    end
+  end
+
+  permissions :create?, :update?, :copy?, :destroy? do
+    context 'admin' do
+      it 'permits' do
+        expect(subject).to permit(admin, CustomEmoji)
+      end
+    end
+
+    context 'not admin' do
+      it 'denies' do
+        expect(subject).to_not permit(john, CustomEmoji)
+      end
+    end
+  end
+end
diff --git a/spec/policies/domain_block_policy_spec.rb b/spec/policies/domain_block_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..aea50ec0fde33ebb2f6a2acd04c599105a981e64
--- /dev/null
+++ b/spec/policies/domain_block_policy_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe DomainBlockPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index?, :show?, :create?, :destroy? do
+    context 'admin' do
+      it 'permits' do
+        expect(subject).to permit(admin, DomainBlock)
+      end
+    end
+
+    context 'not admin' do
+      it 'denies' do
+        expect(subject).to_not permit(john, DomainBlock)
+      end
+    end
+  end
+end
diff --git a/spec/policies/email_domain_block_policy_spec.rb b/spec/policies/email_domain_block_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a3e825e078942d1d67d1ac89c42bb55efc5403cc
--- /dev/null
+++ b/spec/policies/email_domain_block_policy_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe EmailDomainBlockPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index?, :create?, :destroy? do
+    context 'admin' do
+      it 'permits' do
+        expect(subject).to permit(admin, EmailDomainBlock)
+      end
+    end
+
+    context 'not admin' do
+      it 'denies' do
+        expect(subject).to_not permit(john, EmailDomainBlock)
+      end
+    end
+  end
+end
diff --git a/spec/policies/instance_policy_spec.rb b/spec/policies/instance_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..77a3bde3fb52c9a1e017fb825a9aa6be1c50ecd9
--- /dev/null
+++ b/spec/policies/instance_policy_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe InstancePolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index? do
+    context 'admin' do
+      it 'permits' do
+        expect(subject).to permit(admin, Instance)
+      end
+    end
+
+    context 'not admin' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Instance)
+      end
+    end
+  end
+end
diff --git a/spec/policies/invite_policy_spec.rb b/spec/policies/invite_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e391455be3eb1f547f40ee6ddda8d8306084387d
--- /dev/null
+++ b/spec/policies/invite_policy_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe InvitePolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index? do
+    context 'staff?' do
+      it 'permits' do
+        expect(subject).to permit(admin, Invite)
+      end
+    end
+  end
+
+  permissions :create? do
+    context 'min_required_role?' do
+      it 'permits' do
+        allow_any_instance_of(described_class).to receive(:min_required_role?) { true }
+        expect(subject).to permit(john, Invite)
+      end
+    end
+
+    context 'not min_required_role?' do
+      it 'denies' do
+        allow_any_instance_of(described_class).to receive(:min_required_role?) { false }
+        expect(subject).to_not permit(john, Invite)
+      end
+    end
+  end
+
+  permissions :deactivate_all? do
+    context 'admin?' do
+      it 'permits' do
+        expect(subject).to permit(admin, Invite)
+      end
+    end
+
+    context 'not admin?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Invite)
+      end
+    end
+  end
+
+  permissions :destroy? do
+    context 'owner?' do
+      it 'permits' do
+        expect(subject).to permit(john, Fabricate(:invite, user: john.user))
+      end
+    end
+
+    context 'not owner?' do
+      context 'Setting.min_invite_role == "admin"' do
+        before do
+          Setting.min_invite_role = 'admin'
+        end
+
+        context 'admin?' do
+          it 'permits' do
+            expect(subject).to permit(admin, Fabricate(:invite))
+          end
+        end
+
+        context 'not admin?' do
+          it 'denies' do
+            expect(subject).to_not permit(john, Fabricate(:invite))
+          end
+        end
+      end
+
+      context 'Setting.min_invite_role != "admin"' do
+        before do
+          Setting.min_invite_role = 'else'
+        end
+
+        context 'staff?' do
+          it 'permits' do
+            expect(subject).to permit(admin, Fabricate(:invite))
+          end
+        end
+
+        context 'not staff?' do
+          it 'denies' do
+            expect(subject).to_not permit(john, Fabricate(:invite))
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/spec/policies/relay_policy_spec.rb b/spec/policies/relay_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..640f27d5475eb9eb6ea50435f3f6f32e3fe35aca
--- /dev/null
+++ b/spec/policies/relay_policy_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe RelayPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :update? do
+    context 'admin?' do
+      it 'permits' do
+        expect(subject).to permit(admin, Relay)
+      end
+    end
+
+    context '!admin?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Relay)
+      end
+    end
+  end
+end
diff --git a/spec/policies/report_note_policy_spec.rb b/spec/policies/report_note_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..596d7d7a95fa07ca4fc35facdc1a5aa7c39ac4a1
--- /dev/null
+++ b/spec/policies/report_note_policy_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe ReportNotePolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :create? do
+    context 'staff?' do
+      it 'permits' do
+        expect(subject).to permit(admin, ReportNote)
+      end
+    end
+
+    context '!staff?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, ReportNote)
+      end
+    end
+  end
+
+  permissions :destroy? do
+    context 'admin?' do
+      it 'permit' do
+        expect(subject).to permit(admin, ReportNote)
+      end
+    end
+
+    context 'admin?' do
+      context 'owner?' do
+        it 'permit' do
+          report_note = Fabricate(:report_note, account: john)
+          expect(subject).to permit(john, report_note)
+        end
+      end
+
+      context '!owner?' do
+        it 'denies' do
+          report_note = Fabricate(:report_note)
+          expect(subject).to_not permit(john, report_note)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/policies/report_policy_spec.rb b/spec/policies/report_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c9ae1e87a909e71f94b8ef6763fd02a07ff187c8
--- /dev/null
+++ b/spec/policies/report_policy_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe ReportPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :update?, :index?, :show? do
+    context 'staff?' do
+      it 'permits' do
+        expect(subject).to permit(admin, Report)
+      end
+    end
+
+    context '!staff?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Report)
+      end
+    end
+  end
+end
diff --git a/spec/policies/settings_policy_spec.rb b/spec/policies/settings_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..92f1f4869a9e9da78de69f08baca284afaa1362e
--- /dev/null
+++ b/spec/policies/settings_policy_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe SettingsPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :update?, :show? do
+    context 'admin?' do
+      it 'permits' do
+        expect(subject).to permit(admin, Settings)
+      end
+    end
+
+    context '!admin?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Settings)
+      end
+    end
+  end
+end
diff --git a/spec/policies/status_policy_spec.rb b/spec/policies/status_policy_spec.rb
index bacb8fd9e3fe9e62d4c80367022cc8ce0ac833af..1cddf4abd57da9a0df420ae141f4e9d403c9f38a 100644
--- a/spec/policies/status_policy_spec.rb
+++ b/spec/policies/status_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 require 'pundit/rspec'
 
@@ -106,4 +108,30 @@ RSpec.describe StatusPolicy, type: :model do
       expect(subject).to_not permit(nil, status)
     end
   end
+
+  permissions :favourite? do
+    it 'grants access when viewer is not blocked' do
+      follow         = Fabricate(:follow)
+      status.account = follow.target_account
+
+      expect(subject).to permit(follow.account, status)
+    end
+
+    it 'denies when viewer is blocked' do
+      block          = Fabricate(:block)
+      status.account = block.target_account
+
+      expect(subject).to_not permit(block.account, status)
+    end
+  end
+
+  permissions :index?, :update? do
+    it 'grants access if staff' do
+      expect(subject).to permit(admin.account)
+    end
+
+    it 'denies access unless staff' do
+      expect(subject).to_not permit(alice)
+    end
+  end
 end
diff --git a/spec/policies/subscription_policy_spec.rb b/spec/policies/subscription_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..21d60c15fc0c95d55c15828ae23d98e65cd3a868
--- /dev/null
+++ b/spec/policies/subscription_policy_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe SubscriptionPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index? do
+    context 'admin?' do
+      it 'permits' do
+        expect(subject).to permit(admin, Subscription)
+      end
+    end
+
+    context '!admin?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Subscription)
+      end
+    end
+  end
+end
diff --git a/spec/policies/tag_policy_spec.rb b/spec/policies/tag_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c7afaa7c93d0f6eab29832da761cb4812a5861ee
--- /dev/null
+++ b/spec/policies/tag_policy_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe TagPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index?, :hide?, :unhide? do
+    context 'staff?' do
+      it 'permits' do
+        expect(subject).to permit(admin, Tag)
+      end
+    end
+
+    context '!staff?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Tag)
+      end
+    end
+  end
+end
diff --git a/spec/policies/user_policy_spec.rb b/spec/policies/user_policy_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e37904f048e618c8f789f82a7e130a4ac2919e51
--- /dev/null
+++ b/spec/policies/user_policy_spec.rb
@@ -0,0 +1,167 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe UserPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :reset_password?, :change_email? do
+    context 'staff?' do
+      context '!record.staff?' do
+        it 'permits' do
+          expect(subject).to permit(admin, john.user)
+        end
+      end
+
+      context 'record.staff?' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, admin.user)
+        end
+      end
+    end
+
+    context '!staff?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, User)
+      end
+    end
+  end
+
+  permissions :disable_2fa? do
+    context 'admin?' do
+      context '!record.staff?' do
+        it 'permits' do
+          expect(subject).to permit(admin, john.user)
+        end
+      end
+
+      context 'record.staff?' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, admin.user)
+        end
+      end
+    end
+
+    context '!admin?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, User)
+      end
+    end
+  end
+
+  permissions :confirm? do
+    context 'staff?' do
+      context '!record.confirmed?' do
+        it 'permits' do
+          john.user.update(confirmed_at: nil)
+          expect(subject).to permit(admin, john.user)
+        end
+      end
+
+      context 'record.confirmed?' do
+        it 'denies' do
+          john.user.confirm!
+          expect(subject).to_not permit(admin, john.user)
+        end
+      end
+    end
+
+    context '!staff?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, User)
+      end
+    end
+  end
+
+  permissions :enable? do
+    context 'staff?' do
+      it 'permits' do
+        expect(subject).to permit(admin, User)
+      end
+    end
+
+    context '!staff?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, User)
+      end
+    end
+  end
+
+  permissions :disable? do
+    context 'staff?' do
+      context '!record.admin?' do
+        it 'permits' do
+          expect(subject).to permit(admin, john.user)
+        end
+      end
+
+      context 'record.admin?' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, admin.user)
+        end
+      end
+    end
+
+    context '!staff?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, User)
+      end
+    end
+  end
+
+  permissions :promote? do
+    context 'admin?' do
+      context 'promoteable?' do
+        it 'permits' do
+          expect(subject).to permit(admin, john.user)
+        end
+      end
+
+      context '!promoteable?' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, admin.user)
+        end
+      end
+    end
+
+    context '!admin?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, User)
+      end
+    end
+  end
+
+  permissions :demote? do
+    context 'admin?' do
+      context '!record.admin?' do
+        context 'demoteable?' do
+          it 'permits' do
+            john.user.update(moderator: true)
+            expect(subject).to permit(admin, john.user)
+          end
+        end
+
+        context '!demoteable?' do
+          it 'denies' do
+            expect(subject).to_not permit(admin, john.user)
+          end
+        end
+      end
+
+      context 'record.admin?' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, admin.user)
+        end
+      end
+    end
+
+    context '!admin?' do
+      it 'denies' do
+        expect(subject).to_not permit(john, User)
+      end
+    end
+  end
+end
diff --git a/spec/presenters/instance_presenter_spec.rb b/spec/presenters/instance_presenter_spec.rb
index 006403925fe52cd2e80d216d5fd006b712531ed7..0babc1b0c8a36e1e47e034acf05674a11bbf81e4 100644
--- a/spec/presenters/instance_presenter_spec.rb
+++ b/spec/presenters/instance_presenter_spec.rb
@@ -111,4 +111,37 @@ describe InstancePresenter do
       expect(instance_presenter.domain_count).to eq(345)
     end
   end
+
+  describe '#version_number' do
+    it 'returns Mastodon::Version' do
+      expect(instance_presenter.version_number).to be(Mastodon::Version)
+    end
+  end
+
+  describe '#source_url' do
+    it 'returns "https://github.com/tootsuite/mastodon"' do
+      expect(instance_presenter.source_url).to eq('https://github.com/tootsuite/mastodon')
+    end
+  end
+
+  describe '#thumbnail' do
+    it 'returns SiteUpload' do
+      thumbnail = Fabricate(:site_upload, var: 'thumbnail')
+      expect(instance_presenter.thumbnail).to eq(thumbnail)
+    end
+  end
+
+  describe '#hero' do
+    it 'returns SiteUpload' do
+      hero = Fabricate(:site_upload, var: 'hero')
+      expect(instance_presenter.hero).to eq(hero)
+    end
+  end
+
+  describe '#mascot' do
+    it 'returns SiteUpload' do
+      mascot = Fabricate(:site_upload, var: 'mascot')
+      expect(instance_presenter.mascot).to eq(mascot)
+    end
+  end
 end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index c575128e408bc22bde80194cf97a5a5cf67e358d..3a5e7491e515198888d2bc25733fab67fbec2a97 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -71,11 +71,11 @@ RSpec::Sidekiq.configure do |config|
 end
 
 def request_fixture(name)
-  File.read(File.join(Rails.root, 'spec', 'fixtures', 'requests', name))
+  File.read(Rails.root.join('spec', 'fixtures', 'requests', name))
 end
 
 def attachment_fixture(name)
-  File.open(File.join(Rails.root, 'spec', 'fixtures', 'files', name))
+  File.open(Rails.root.join('spec', 'fixtures', 'files', name))
 end
 
 def stub_jsonld_contexts!
diff --git a/spec/services/activitypub/fetch_remote_account_service_spec.rb b/spec/services/activitypub/fetch_remote_account_service_spec.rb
index dba55c034619660c72ebeaa31b0f31f5fc9ad15a..aa13f0a9b7936774212ffa16b2f7148206a1d4dd 100644
--- a/spec/services/activitypub/fetch_remote_account_service_spec.rb
+++ b/spec/services/activitypub/fetch_remote_account_service_spec.rb
@@ -59,7 +59,6 @@ RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
       it 'returns nil' do
         expect(account).to be_nil
       end
-
     end
 
     context 'when URI and WebFinger share the same host' do
@@ -119,5 +118,11 @@ RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
 
       include_examples 'sets profile data'
     end
+
+    context 'with wrong id' do
+      it 'does not create account' do
+        expect(subject.call('https://fake.address/@foo', prefetched_body: Oj.dump(actor))).to be_nil
+      end
+    end
   end
 end
diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb
index 549eb80fa6454fbc790fefb879b151a6344bb4bf..9ae4099969405194c47006a7c3313a6afb5ab869 100644
--- a/spec/services/activitypub/fetch_remote_status_service_spec.rb
+++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb
@@ -70,5 +70,27 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do
         expect(strip_tags(status.text)).to eq "Nyan Cat 10 hours remix https://#{valid_domain}/watch?v=12345"
       end
     end
+
+    context 'with wrong id' do
+      let(:note) do
+        {
+          '@context': 'https://www.w3.org/ns/activitystreams',
+          id: "https://real.address/@foo/1234",
+          type: 'Note',
+          content: 'Lorem ipsum',
+          attributedTo: ActivityPub::TagManager.instance.uri_for(sender),
+        }
+      end
+
+      let(:object) do
+        temp = note.dup
+        temp[:id] = 'https://fake.address/@foo/5678'
+        temp
+      end
+
+      it 'does not create status' do
+        expect(sender.statuses.first).to be_nil
+      end
+    end
   end
 end
diff --git a/spec/services/activitypub/process_collection_service_spec.rb b/spec/services/activitypub/process_collection_service_spec.rb
index e46f0ae4501892ecf80d331cf53302c68fa5613b..b3baf6b6b545140891cfdf533ebf0967b5d22b14 100644
--- a/spec/services/activitypub/process_collection_service_spec.rb
+++ b/spec/services/activitypub/process_collection_service_spec.rb
@@ -26,15 +26,15 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
     context 'when actor differs from sender' do
       let(:forwarder) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/other_account') }
 
-      it 'processes payload with sender if no signature exists' do
-        expect_any_instance_of(ActivityPub::LinkedDataSignature).not_to receive(:verify_account!)
-        expect(ActivityPub::Activity).to receive(:factory).with(instance_of(Hash), forwarder, instance_of(Hash))
+      it 'does not process payload if no signature exists' do
+        expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_account!).and_return(nil)
+        expect(ActivityPub::Activity).not_to receive(:factory)
 
         subject.call(json, forwarder)
       end
 
       it 'processes payload with actor if valid signature exists' do
-        payload['signature'] = {'type' => 'RsaSignature2017'}
+        payload['signature'] = { 'type' => 'RsaSignature2017' }
 
         expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_account!).and_return(actor)
         expect(ActivityPub::Activity).to receive(:factory).with(instance_of(Hash), actor, instance_of(Hash))
@@ -43,7 +43,7 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
       end
 
       it 'does not process payload if invalid signature exists' do
-        payload['signature'] = {'type' => 'RsaSignature2017'}
+        payload['signature'] = { 'type' => 'RsaSignature2017' }
 
         expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_account!).and_return(nil)
         expect(ActivityPub::Activity).not_to receive(:factory)
diff --git a/spec/services/app_sign_up_service_spec.rb b/spec/services/app_sign_up_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d480df34808ce3c62a48d3109df3cca2e9e5bd18
--- /dev/null
+++ b/spec/services/app_sign_up_service_spec.rb
@@ -0,0 +1,41 @@
+require 'rails_helper'
+
+RSpec.describe AppSignUpService, type: :service do
+  let(:app) { Fabricate(:application, scopes: 'read write') }
+  let(:good_params) { { username: 'alice', password: '12345678', email: 'good@email.com', agreement: true } }
+
+  subject { described_class.new }
+
+  describe '#call' do
+    it 'returns nil when registrations are closed' do
+      Setting.open_registrations = false
+      expect(subject.call(app, good_params)).to be_nil
+    end
+
+    it 'raises an error when params are missing' do
+      expect { subject.call(app, {}) }.to raise_error ActiveRecord::RecordInvalid
+    end
+
+    it 'creates an unconfirmed user with access token' do
+      access_token = subject.call(app, good_params)
+      expect(access_token).to_not be_nil
+      user = User.find_by(id: access_token.resource_owner_id)
+      expect(user).to_not be_nil
+      expect(user.confirmed?).to be false
+    end
+
+    it 'creates access token with the app\'s scopes' do
+      access_token = subject.call(app, good_params)
+      expect(access_token).to_not be_nil
+      expect(access_token.scopes.to_s).to eq 'read write'
+    end
+
+    it 'creates an account' do
+      access_token = subject.call(app, good_params)
+      expect(access_token).to_not be_nil
+      user = User.find_by(id: access_token.resource_owner_id)
+      expect(user).to_not be_nil
+      expect(user.account).to_not be_nil
+    end
+  end
+end
diff --git a/spec/services/batched_remove_status_service_spec.rb b/spec/services/batched_remove_status_service_spec.rb
index 23c122e59b8a72d15826272b1baff899eb2be9a8..e53623449f78d56abce08e5169cd53c72a2558a5 100644
--- a/spec/services/batched_remove_status_service_spec.rb
+++ b/spec/services/batched_remove_status_service_spec.rb
@@ -8,8 +8,8 @@ RSpec.describe BatchedRemoveStatusService, type: :service do
   let!(:jeff)   { Fabricate(:user).account }
   let!(:hank)   { Fabricate(:account, username: 'hank', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
 
-  let(:status1) { PostStatusService.new.call(alice, 'Hello @bob@example.com') }
-  let(:status2) { PostStatusService.new.call(alice, 'Another status') }
+  let(:status1) { PostStatusService.new.call(alice, text: 'Hello @bob@example.com') }
+  let(:status2) { PostStatusService.new.call(alice, text: 'Another status') }
 
   before do
     allow(Redis.current).to receive_messages(publish: nil)
@@ -19,7 +19,7 @@ RSpec.describe BatchedRemoveStatusService, type: :service do
     stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
 
     Fabricate(:subscription, account: alice, callback_url: 'http://example.com/push', confirmed: true, expires_at: 30.days.from_now)
-    jeff.user.update(current_sign_in_at: Time.now)
+    jeff.user.update(current_sign_in_at: Time.zone.now)
     jeff.follow!(alice)
     hank.follow!(alice)
 
diff --git a/spec/services/fetch_atom_service_spec.rb b/spec/services/fetch_atom_service_spec.rb
index bb233c12d1311adb2f02ea5bf24efd0cc1734bb9..495540004e9504d9d782283f7e91dd6379647991 100644
--- a/spec/services/fetch_atom_service_spec.rb
+++ b/spec/services/fetch_atom_service_spec.rb
@@ -57,11 +57,18 @@ RSpec.describe FetchAtomService, type: :service do
       context 'content type is application/atom+xml' do
         let(:content_type) { 'application/atom+xml' }
 
-        it { is_expected.to eq [url, {:prefetched_body=>""}, :ostatus] }
+        it { is_expected.to eq [url, { :prefetched_body => "" }, :ostatus] }
       end
 
-      context 'content_type is json' do
-        let(:content_type) { 'application/activity+json' }
+      context 'content_type is activity+json' do
+        let(:content_type) { 'application/activity+json; charset=utf-8' }
+        let(:body) { json }
+
+        it { is_expected.to eq [1, { prefetched_body: body, id: true }, :activitypub] }
+      end
+
+      context 'content_type is ld+json with profile' do
+        let(:content_type) { 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' }
         let(:body) { json }
 
         it { is_expected.to eq [1, { prefetched_body: body, id: true }, :activitypub] }
diff --git a/spec/services/fetch_link_card_service_spec.rb b/spec/services/fetch_link_card_service_spec.rb
index 88c5339db44929207a7e831408bcf65da6a3515a..50c60aafd1d6dec13d8b5cd06482da34ca14bd4a 100644
--- a/spec/services/fetch_link_card_service_spec.rb
+++ b/spec/services/fetch_link_card_service_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe FetchLinkCardService, type: :service do
     stub_request(:head, 'https://github.com/qbi/WannaCry').to_return(status: 404)
     stub_request(:head, 'http://example.com/test-').to_return(status: 200, headers: { 'Content-Type' => 'text/html' })
     stub_request(:get, 'http://example.com/test-').to_return(request_fixture('idn.txt'))
+    stub_request(:head, 'http://example.com/windows-1251').to_return(status: 200, headers: { 'Content-Type' => 'text/html' })
+    stub_request(:get, 'http://example.com/windows-1251').to_return(request_fixture('windows-1251.txt'))
 
     subject.call(status)
   end
@@ -57,6 +59,15 @@ RSpec.describe FetchLinkCardService, type: :service do
       end
     end
 
+    context do
+      let(:status) { Fabricate(:status, text: 'Check out http://example.com/windows-1251') }
+
+      it 'works with windows-1251' do
+        expect(a_request(:get, 'http://example.com/windows-1251')).to have_been_made.at_least_once
+        expect(status.preview_cards.first.title).to eq('сэмпл текст')
+      end
+    end
+
     context do
       let(:status) { Fabricate(:status, text: 'テストhttp://example.com/日本語') }
 
diff --git a/spec/services/fetch_oembed_service_spec.rb b/spec/services/fetch_oembed_service_spec.rb
index 706eb3f2ae0c5733792aca3622eae3122e103684..5789fb53bebbd168bb5007f72207b0362304123c 100644
--- a/spec/services/fetch_oembed_service_spec.rb
+++ b/spec/services/fetch_oembed_service_spec.rb
@@ -8,6 +8,7 @@ describe FetchOEmbedService, type: :service do
   before do
     stub_request(:get, "https://host.test/provider.json").to_return(status: 404)
     stub_request(:get, "https://host.test/provider.xml").to_return(status: 404)
+    stub_request(:get, "https://host.test/empty_provider.json").to_return(status: 200)
   end
 
   describe 'discover_provider' do
@@ -93,6 +94,23 @@ describe FetchOEmbedService, type: :service do
           expect(subject.call('https://host.test/oembed.html')).to be_nil
         end
       end
+
+      context 'Empty JSON provider is discoverable' do
+        before do
+          stub_request(:get, 'https://host.test/oembed.html').to_return(
+            status: 200,
+            headers: { 'Content-Type': 'text/html' },
+            body: request_fixture('oembed_json_empty.html')
+          )
+        end
+
+        it 'returns new OEmbed::Provider for JSON provider' do
+          subject.call('https://host.test/oembed.html')
+          expect(subject.endpoint_url).to eq 'https://host.test/empty_provider.json'
+          expect(subject.format).to eq :json
+        end
+      end
+
     end
 
     context 'when status code is not 200' do
diff --git a/spec/services/fetch_remote_account_service_spec.rb b/spec/services/fetch_remote_account_service_spec.rb
index 1c3abe8f3c7b0e2359609ad83a723ae1d2f6b0f3..3cd86708be4339746ce8f8ca9a63783e1bd2bc90 100644
--- a/spec/services/fetch_remote_account_service_spec.rb
+++ b/spec/services/fetch_remote_account_service_spec.rb
@@ -1,7 +1,7 @@
 require 'rails_helper'
 
 RSpec.describe FetchRemoteAccountService, type: :service do
-  let(:url) { 'https://example.com' }
+  let(:url) { 'https://example.com/alice' }
   let(:prefetched_body) { nil }
   let(:protocol) { :ostatus }
   subject { FetchRemoteAccountService.new.call(url, prefetched_body, protocol) }
@@ -19,7 +19,7 @@ RSpec.describe FetchRemoteAccountService, type: :service do
   end
 
   let(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
-  let(:xml) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'xml', 'mastodon.atom')) }
+  let(:xml) { File.read(Rails.root.join('spec', 'fixtures', 'xml', 'mastodon.atom')) }
 
   shared_examples 'return Account' do
     it { is_expected.to be_an Account }
@@ -46,6 +46,24 @@ RSpec.describe FetchRemoteAccountService, type: :service do
     end
 
     include_examples 'return Account'
+
+    it 'does not update account information if XML comes from an unverified domain' do
+      feed_xml = <<-XML.squish
+        <?xml version="1.0" encoding="UTF-8"?>
+        <feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:media="http://purl.org/syndication/atommedia" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:statusnet="http://status.net/schema/api/1/">
+          <author>
+            <activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
+            <uri>http://kickass.zone/users/localhost</uri>
+            <name>localhost</name>
+            <poco:preferredUsername>localhost</poco:preferredUsername>
+            <poco:displayName>Villain!!!</poco:displayName>
+          </author>
+        </feed>
+      XML
+
+      returned_account = described_class.new.call('https://real-fake-domains.com/alice', feed_xml, :ostatus)
+      expect(returned_account.display_name).to_not eq 'Villain!!!'
+    end
   end
 
   context 'when prefetched_body is nil' do
diff --git a/spec/services/fetch_remote_status_service_spec.rb b/spec/services/fetch_remote_status_service_spec.rb
index 0df9c329ab28e96ae1f692eec6481504780b6ba9..f9db024b93ab17dcb17988144c9f212bf391ad92 100644
--- a/spec/services/fetch_remote_status_service_spec.rb
+++ b/spec/services/fetch_remote_status_service_spec.rb
@@ -32,4 +32,56 @@ RSpec.describe FetchRemoteStatusService, type: :service do
       expect(status.text).to eq 'Lorem ipsum'
     end
   end
+
+  context 'protocol is :ostatus' do
+    subject { described_class.new }
+
+    before do
+      Fabricate(:account, username: 'tracer', domain: 'real.domain', remote_url: 'https://real.domain/users/tracer')
+    end
+
+    it 'does not create status with author at different domain' do
+      status_body = <<-XML.squish
+        <?xml version="1.0"?>
+        <entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:media="http://purl.org/syndication/atommedia" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:mastodon="http://mastodon.social/schema/1.0">
+          <id>tag:real.domain,2017-04-27:objectId=4487555:objectType=Status</id>
+          <published>2017-04-27T13:49:25Z</published>
+          <updated>2017-04-27T13:49:25Z</updated>
+          <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
+          <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
+          <author>
+            <id>https://real.domain/users/tracer</id>
+            <activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
+            <uri>https://real.domain/users/tracer</uri>
+            <name>tracer</name>
+          </author>
+          <content type="html">Overwatch rocks</content>
+        </entry>
+      XML
+
+      expect(subject.call('https://fake.domain/foo', status_body, :ostatus)).to be_nil
+    end
+
+    it 'does not create status with wrong id when id uses http format' do
+      status_body = <<-XML.squish
+        <?xml version="1.0"?>
+        <entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:media="http://purl.org/syndication/atommedia" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:mastodon="http://mastodon.social/schema/1.0">
+          <id>https://other-real.domain/statuses/123</id>
+          <published>2017-04-27T13:49:25Z</published>
+          <updated>2017-04-27T13:49:25Z</updated>
+          <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
+          <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
+          <author>
+            <id>https://real.domain/users/tracer</id>
+            <activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
+            <uri>https://real.domain/users/tracer</uri>
+            <name>tracer</name>
+          </author>
+          <content type="html">Overwatch rocks</content>
+        </entry>
+      XML
+
+      expect(subject.call('https://real.domain/statuses/456', status_body, :ostatus)).to be_nil
+    end
+  end
 end
diff --git a/spec/services/hashtag_query_service_spec.rb b/spec/services/hashtag_query_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..24282d2f0672e1defd94bd4bcc100bfe736c04f0
--- /dev/null
+++ b/spec/services/hashtag_query_service_spec.rb
@@ -0,0 +1,60 @@
+require 'rails_helper'
+
+describe HashtagQueryService, type: :service do
+  describe '.call' do
+    let(:account) { Fabricate(:account) }
+    let(:tag1) { Fabricate(:tag) }
+    let(:tag2) { Fabricate(:tag) }
+    let!(:status1) { Fabricate(:status, tags: [tag1]) }
+    let!(:status2) { Fabricate(:status, tags: [tag2]) }
+    let!(:both) { Fabricate(:status, tags: [tag1, tag2]) }
+
+    it 'can add tags in "any" mode' do
+      results = subject.call(tag1, { any: [tag2.name] })
+      expect(results).to include status1
+      expect(results).to include status2
+      expect(results).to include both
+    end
+
+    it 'can remove tags in "all" mode' do
+      results = subject.call(tag1, { all: [tag2.name] })
+      expect(results).to_not include status1
+      expect(results).to_not include status2
+      expect(results).to     include both
+    end
+
+    it 'can remove tags in "none" mode' do
+      results = subject.call(tag1, { none: [tag2.name] })
+      expect(results).to     include status1
+      expect(results).to_not include status2
+      expect(results).to_not include both
+    end
+
+    it 'ignores an invalid mode' do
+      results = subject.call(tag1, { wark: [tag2.name] })
+      expect(results).to     include status1
+      expect(results).to_not include status2
+      expect(results).to     include both
+    end
+
+    it 'handles being passed non existant tag names' do
+      results = subject.call(tag1, { any: ['wark'] })
+      expect(results).to     include status1
+      expect(results).to_not include status2
+      expect(results).to     include both
+    end
+
+    it 'can restrict to an account' do
+      BlockService.new.call(account, status1.account)
+      results = subject.call(tag1, { none: [tag2.name] }, account)
+      expect(results).to_not include status1
+    end
+
+    it 'can restrict to local' do
+      status1.account.update(domain: 'example.com')
+      status1.update(local: false, uri: 'example.com/toot')
+      results = subject.call(tag1, { any: [tag2.name] }, nil, true)
+      expect(results).to_not include status1
+    end
+  end
+end
diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb
index d3466794314bc653f9e00ad5e89ce7cc00fa3855..39a681abbf70381aaf2cbc69cf05b195ee7a9dd1 100644
--- a/spec/services/notify_service_spec.rb
+++ b/spec/services/notify_service_spec.rb
@@ -104,9 +104,9 @@ RSpec.describe NotifyService, type: :service do
       is_expected.to change(Notification, :count)
     end
 
-    it 'hides reblogs when disabled' do
-      recipient.follow!(sender, reblogs: false)
-      is_expected.to_not change(Notification, :count)
+    it 'shows reblogs when disabled' do
+      recipient.follow!(sender, reblogs: true)
+      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 40fa8fbefaab55ef94e950d8e253455af3f602d3..3774fed6f3e8a641e5bac4b515060ff9c2e5b5d8 100644
--- a/spec/services/post_status_service_spec.rb
+++ b/spec/services/post_status_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe PostStatusService, type: :service do
     account = Fabricate(:account)
     text = "test status update"
 
-    status = subject.call(account, text)
+    status = subject.call(account, text: text)
 
     expect(status).to be_persisted
     expect(status.text).to eq text
@@ -18,13 +18,37 @@ RSpec.describe PostStatusService, type: :service do
     account = Fabricate(:account)
     text = "test status update"
 
-    status = subject.call(account, text, in_reply_to_status)
+    status = subject.call(account, text: text, thread: in_reply_to_status)
 
     expect(status).to be_persisted
     expect(status.text).to eq text
     expect(status.thread).to eq in_reply_to_status
   end
 
+  it 'schedules a status' do
+    account = Fabricate(:account)
+    future  = Time.now.utc + 2.hours
+
+    status = subject.call(account, text: 'Hi future!', scheduled_at: future)
+
+    expect(status).to be_a ScheduledStatus
+    expect(status.scheduled_at).to eq future
+    expect(status.params['text']).to eq 'Hi future!'
+  end
+
+  it 'creates response to the original status of boost' do
+    boosted_status = Fabricate(:status)
+    in_reply_to_status = Fabricate(:status, reblog: boosted_status)
+    account = Fabricate(:account)
+    text = "test status update"
+
+    status = subject.call(account, text: text, thread: in_reply_to_status)
+
+    expect(status).to be_persisted
+    expect(status.text).to eq text
+    expect(status.thread).to eq boosted_status
+  end
+
   it 'creates a sensitive status' do
     status = create_status_with_options(sensitive: true)
 
@@ -55,6 +79,13 @@ RSpec.describe PostStatusService, type: :service do
     expect(status.visibility).to eq "private"
   end
 
+  it 'creates a status with limited visibility for silenced users' do
+    status = subject.call(Fabricate(:account, silenced: true), text: 'test', visibility: :public)
+
+    expect(status).to be_persisted
+    expect(status.visibility).to eq "unlisted"
+  end
+
   it 'creates a status for the given application' do
     application = Fabricate(:application)
 
@@ -68,7 +99,7 @@ RSpec.describe PostStatusService, type: :service do
     account = Fabricate(:account)
     text = 'This is an English text.'
 
-    status = subject.call(account, text)
+    status = subject.call(account, text: text)
 
     expect(status.language).to eq 'en'
   end
@@ -79,7 +110,7 @@ RSpec.describe PostStatusService, type: :service do
     allow(ProcessMentionsService).to receive(:new).and_return(mention_service)
     account = Fabricate(:account)
 
-    status = subject.call(account, "test status update")
+    status = subject.call(account, text: "test status update")
 
     expect(ProcessMentionsService).to have_received(:new)
     expect(mention_service).to have_received(:call).with(status)
@@ -91,7 +122,7 @@ RSpec.describe PostStatusService, type: :service do
     allow(ProcessHashtagsService).to receive(:new).and_return(hashtags_service)
     account = Fabricate(:account)
 
-    status = subject.call(account, "test status update")
+    status = subject.call(account, text: "test status update")
 
     expect(ProcessHashtagsService).to have_received(:new)
     expect(hashtags_service).to have_received(:call).with(status)
@@ -104,7 +135,7 @@ RSpec.describe PostStatusService, type: :service do
 
     account = Fabricate(:account)
 
-    status = subject.call(account, "test status update")
+    status = subject.call(account, text: "test status update")
 
     expect(DistributionWorker).to have_received(:perform_async).with(status.id)
     expect(Pubsubhubbub::DistributionWorker).to have_received(:perform_async).with(status.stream_entry.id)
@@ -115,7 +146,7 @@ RSpec.describe PostStatusService, type: :service do
     allow(LinkCrawlWorker).to receive(:perform_async)
     account = Fabricate(:account)
 
-    status = subject.call(account, "test status update")
+    status = subject.call(account, text: "test status update")
 
     expect(LinkCrawlWorker).to have_received(:perform_async).with(status.id)
   end
@@ -126,8 +157,7 @@ RSpec.describe PostStatusService, type: :service do
 
     status = subject.call(
       account,
-      "test status update",
-      nil,
+      text: "test status update",
       media_ids: [media.id],
     )
 
@@ -140,8 +170,7 @@ RSpec.describe PostStatusService, type: :service do
     expect do
       subject.call(
         account,
-        "test status update",
-        nil,
+        text: "test status update",
         media_ids: [
           Fabricate(:media_attachment, account: account),
           Fabricate(:media_attachment, account: account),
@@ -162,8 +191,7 @@ RSpec.describe PostStatusService, type: :service do
     expect do
       subject.call(
         account,
-        "test status update",
-        nil,
+        text: "test status update",
         media_ids: [
           Fabricate(:media_attachment, type: :video, account: account),
           Fabricate(:media_attachment, type: :image, account: account),
@@ -177,12 +205,12 @@ RSpec.describe PostStatusService, type: :service do
 
   it 'returns existing status when used twice with idempotency key' do
     account = Fabricate(:account)
-    status1 = subject.call(account, 'test', nil, idempotency: 'meepmeep')
-    status2 = subject.call(account, 'test', nil, idempotency: 'meepmeep')
+    status1 = subject.call(account, text: 'test', idempotency: 'meepmeep')
+    status2 = subject.call(account, text: 'test', idempotency: 'meepmeep')
     expect(status2.id).to eq status1.id
   end
 
   def create_status_with_options(**options)
-    subject.call(Fabricate(:account), 'test', nil, options)
+    subject.call(Fabricate(:account), options.merge(text: 'test'))
   end
 end
diff --git a/spec/services/process_feed_service_spec.rb b/spec/services/process_feed_service_spec.rb
index d8b06506361228382dc432fdefe04b3899fde3f2..9d3465f3f8ddac3eb9ce125d41b92fc0681a7507 100644
--- a/spec/services/process_feed_service_spec.rb
+++ b/spec/services/process_feed_service_spec.rb
@@ -4,7 +4,7 @@ RSpec.describe ProcessFeedService, type: :service do
   subject { ProcessFeedService.new }
 
   describe 'processing a feed' do
-    let(:body) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'xml', 'mastodon.atom')) }
+    let(:body) { File.read(Rails.root.join('spec', 'fixtures', 'xml', 'mastodon.atom')) }
     let(:account) { Fabricate(:account, username: 'localhost', domain: 'kickass.zone') }
 
     before do
@@ -166,7 +166,7 @@ XML
     expect(created_statuses.first.reblog.text).to eq 'Overwatch rocks'
   end
 
-  it 'ignores reblogs if it failed to retreive reblogged statuses' do
+  it 'ignores reblogs if it failed to retrieve reblogged statuses' do
     stub_request(:get, 'https://overwatch.com/users/tracer/updates/1').to_return(status: 404)
 
     actor = Fabricate(:account, username: 'tracer', domain: 'overwatch.com')
diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb
index 2134f51fda7a9482c40f48c3634d3fc4a7956b0f..7bba83a60213f7edd345580834bb9f5b2534837c 100644
--- a/spec/services/remove_status_service_spec.rb
+++ b/spec/services/remove_status_service_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe RemoveStatusService, type: :service do
     jeff.follow!(alice)
     hank.follow!(alice)
 
-    @status = PostStatusService.new.call(alice, 'Hello @bob@example.com')
+    @status = PostStatusService.new.call(alice, text: 'Hello @bob@example.com')
     Fabricate(:status, account: bill, reblog: @status, uri: 'hoge')
     subject.call(@status)
   end
diff --git a/spec/services/report_service_spec.rb b/spec/services/report_service_spec.rb
index 2c392d37684f57b8c96ef1e96f6297b792db5d68..e8b094c89b2b686ca291e00537b8f11f737184c5 100644
--- a/spec/services/report_service_spec.rb
+++ b/spec/services/report_service_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
 RSpec.describe ReportService, type: :service do
   subject { described_class.new }
 
-  let(:source_account) { Fabricate(:account) }
+  let(:source_account) { Fabricate(:user).account }
 
   context 'for a remote account' do
     let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
@@ -22,4 +22,22 @@ RSpec.describe ReportService, type: :service do
       expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made
     end
   end
+
+  context 'when other reports already exist for the same target' do
+    let!(:target_account) { Fabricate(:account) }
+    let!(:other_report)   { Fabricate(:report, target_account: target_account) }
+
+    subject do
+      -> {  described_class.new.call(source_account, target_account) }
+    end
+
+    before do
+      ActionMailer::Base.deliveries.clear
+      source_account.user.settings.notification_emails['report'] = true
+    end
+
+    it 'does not send an e-mail' do
+      is_expected.to_not change(ActionMailer::Base.deliveries, :count).from(0)
+    end
+  end
 end
diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb
index dd7561587d65d26b2e55b1ca64238884e5e68306..27a85af7c9778bd1469fc585af837396d8d41609 100644
--- a/spec/services/resolve_account_service_spec.rb
+++ b/spec/services/resolve_account_service_spec.rb
@@ -119,8 +119,6 @@ RSpec.describe ResolveAccountService, type: :service do
         expect(account.actor_type).to eq 'Person'
       end
     end
-
-    pending
   end
 
   it 'processes one remote account at a time using locks' do
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
index 673de523385c27ca8bc00cb6887dfa5d0b7fd0a4..671080f1d980e68936c3ddb9b613bf63dc8ac98f 100644
--- a/spec/services/search_service_spec.rb
+++ b/spec/services/search_service_spec.rb
@@ -29,7 +29,7 @@ describe SearchService, type: :service do
           allow(ResolveURLService).to receive(:new).and_return(service)
           results = subject.call(@query, 10)
 
-          expect(service).to have_received(:call).with(@query)
+          expect(service).to have_received(:call).with(@query, on_behalf_of: nil)
           expect(results).to eq empty_results
         end
       end
@@ -41,7 +41,7 @@ describe SearchService, type: :service do
           allow(ResolveURLService).to receive(:new).and_return(service)
 
           results = subject.call(@query, 10)
-          expect(service).to have_received(:call).with(@query)
+          expect(service).to have_received(:call).with(@query, on_behalf_of: nil)
           expect(results).to eq empty_results.merge(accounts: [account])
         end
       end
@@ -53,7 +53,7 @@ describe SearchService, type: :service do
           allow(ResolveURLService).to receive(:new).and_return(service)
 
           results = subject.call(@query, 10)
-          expect(service).to have_received(:call).with(@query)
+          expect(service).to have_received(:call).with(@query, on_behalf_of: nil)
           expect(results).to eq empty_results.merge(statuses: [status])
         end
       end
diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb
index fd303a9d5bb920278c11593ae859e764734c848b..8a5bd33010c2cfd90f464f542368ea236e75c10a 100644
--- a/spec/services/suspend_account_service_spec.rb
+++ b/spec/services/suspend_account_service_spec.rb
@@ -2,6 +2,11 @@ require 'rails_helper'
 
 RSpec.describe SuspendAccountService, type: :service do
   describe '#call' 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(account) }
     end
@@ -14,6 +19,8 @@ RSpec.describe SuspendAccountService, type: :service do
     let!(:active_relationship) { Fabricate(:follow, account: account) }
     let!(:passive_relationship) { Fabricate(:follow, target_account: account) }
     let!(:subscription) { Fabricate(:subscription, account: 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) }
 
     it 'deletes associated records' do
       is_expected.to change {
@@ -29,5 +36,11 @@ RSpec.describe SuspendAccountService, type: :service do
         ].map(&:count)
       }.from([1, 1, 1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0, 0, 0])
     end
+
+    it 'sends a delete actor activity to all known inboxes' do
+      subject.call
+      expect(a_request(:post, "https://alice.com/inbox")).to have_been_made.once
+      expect(a_request(:post, "https://bob.com/inbox")).to have_been_made.once
+    end
   end
 end
diff --git a/spec/services/unfollow_service_spec.rb b/spec/services/unfollow_service_spec.rb
index c5914c81820b88d9c9d68f36401d8c9e005ff14e..8a2881ab17f29e26811411d397fadce0fb4d6265 100644
--- a/spec/services/unfollow_service_spec.rb
+++ b/spec/services/unfollow_service_spec.rb
@@ -56,4 +56,22 @@ RSpec.describe UnfollowService, type: :service do
       expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
     end
   end
+
+  describe 'remote ActivityPub (reverse)' do
+    let(:bob) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox')).account }
+
+    before do
+      bob.follow!(sender)
+      stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
+      subject.call(bob, sender)
+    end
+
+    it 'destroys the following relation' do
+      expect(bob.following?(sender)).to be false
+    end
+
+    it 'sends a reject activity' do
+      expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once
+    end
+  end
 end
diff --git a/spec/services/update_remote_profile_service_spec.rb b/spec/services/update_remote_profile_service_spec.rb
index 7ac3a809a7c82768c141c16cbd40e76d5faed24e..f3ea70b801b7ff943d08c95241e1b0a1435351dc 100644
--- a/spec/services/update_remote_profile_service_spec.rb
+++ b/spec/services/update_remote_profile_service_spec.rb
@@ -1,7 +1,7 @@
 require 'rails_helper'
 
 RSpec.describe UpdateRemoteProfileService, type: :service do
-  let(:xml) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'push', 'feed.atom')) }
+  let(:xml) { File.read(Rails.root.join('spec', 'fixtures', 'push', 'feed.atom')) }
 
   subject { UpdateRemoteProfileService.new }
 
diff --git a/spec/services/verify_link_service_spec.rb b/spec/services/verify_link_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2edcdb75f12494e499a0b1f31a67b75ae9a3e50e
--- /dev/null
+++ b/spec/services/verify_link_service_spec.rb
@@ -0,0 +1,109 @@
+require 'rails_helper'
+
+RSpec.describe VerifyLinkService, type: :service do
+  subject { described_class.new }
+
+  context 'given a local account' do
+    let(:account) { Fabricate(:account, username: 'alice') }
+    let(:field)   { Account::Field.new(account, 'name' => 'Website', 'value' => 'http://example.com') }
+
+    before do
+      stub_request(:head, 'https://redirect.me/abc').to_return(status: 301, headers: { 'Location' => ActivityPub::TagManager.instance.url_for(account) })
+      stub_request(:get, 'http://example.com').to_return(status: 200, body: html)
+      subject.call(field)
+    end
+
+    context 'when a link contains an <a> back' do
+      let(:html) do
+        <<-HTML
+          <!doctype html>
+          <body>
+            <a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me">Follow me on Mastodon</a>
+          </body>
+        HTML
+      end
+
+      it 'marks the field as verified' do
+        expect(field.verified?).to be true
+      end
+    end
+
+    context 'when a link contains an <a rel="noopener"> back' do
+      let(:html) do
+        <<-HTML
+          <!doctype html>
+          <body>
+            <a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="noopener me" target="_blank">Follow me on Mastodon</a>
+          </body>
+        HTML
+      end
+
+      it 'marks the field as verified' do
+        expect(field.verified?).to be true
+      end
+    end
+
+    context 'when a link contains a <link> back' do
+      let(:html) do
+        <<-HTML
+          <!doctype html>
+          <head>
+            <link type="text/html" href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me" />
+          </head>
+        HTML
+      end
+
+      it 'marks the field as verified' do
+        expect(field.verified?).to be true
+      end
+    end
+
+    context 'when a link goes through a redirect back' do
+      let(:html) do
+        <<-HTML
+          <!doctype html>
+          <head>
+            <link type="text/html" href="https://redirect.me/abc" rel="me" />
+          </head>
+        HTML
+      end
+
+      it 'marks the field as verified' do
+        expect(field.verified?).to be true
+      end
+    end
+
+    context 'when a link does not contain a link back' do
+      let(:html) { '' }
+
+      it 'marks the field as verified' do
+        expect(field.verified?).to be false
+      end
+    end
+  end
+
+  context 'given a remote account' do
+    let(:account) { Fabricate(:account, username: 'alice', domain: 'example.com', url: 'https://profile.example.com/alice') }
+    let(:field)   { Account::Field.new(account, 'name' => 'Website', 'value' => '<a href="http://example.com" rel="me"><span class="invisible">http://</span><span class="">example.com</span><span class="invisible"></span></a>') }
+
+    before do
+      stub_request(:get, 'http://example.com').to_return(status: 200, body: html)
+      subject.call(field)
+    end
+
+    context 'when a link contains an <a> back' do
+      let(:html) do
+        <<-HTML
+          <!doctype html>
+          <body>
+            <a href="https://profile.example.com/alice" rel="me">Follow me on Mastodon</a>
+          </body>
+        HTML
+      end
+
+      it 'marks the field as verified' do
+        expect(field.verified?).to be true
+      end
+    end
+  end
+end
diff --git a/spec/validators/blacklisted_email_validator_spec.rb b/spec/validators/blacklisted_email_validator_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d2e442f4ab40bc71d219660053693bc9470c5f20
--- /dev/null
+++ b/spec/validators/blacklisted_email_validator_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe BlacklistedEmailValidator, type: :validator do
+  describe '#validate' do
+    let(:user)   { double(email: 'info@mail.com', errors: errors) }
+    let(:errors) { double(add: nil) }
+
+    before do
+      allow_any_instance_of(described_class).to receive(:blocked_email?) { blocked_email }
+      described_class.new.validate(user)
+    end
+
+    context 'blocked_email?' do
+      let(:blocked_email) { true }
+
+      it 'calls errors.add' do
+        expect(errors).to have_received(:add).with(:email, I18n.t('users.invalid_email'))
+      end
+    end
+
+    context '!blocked_email?' do
+      let(:blocked_email) { false }
+
+      it 'not calls errors.add' do
+        expect(errors).not_to have_received(:add).with(:email, I18n.t('users.invalid_email'))
+      end
+    end
+  end
+end
diff --git a/spec/validators/disallowed_hashtags_validator_spec.rb b/spec/validators/disallowed_hashtags_validator_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8ec1302ab9f6b6bd13613eaeb38cbf7a5da15e93
--- /dev/null
+++ b/spec/validators/disallowed_hashtags_validator_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe DisallowedHashtagsValidator, type: :validator do
+  describe '#validate' do
+    before do
+      allow_any_instance_of(described_class).to receive(:select_tags) { tags }
+      described_class.new.validate(status)
+    end
+
+    let(:status) { double(errors: errors, local?: local, reblog?: reblog, text: '') }
+    let(:errors) { double(add: nil) }
+
+    context 'unless status.local? && !status.reblog?' do
+      let(:local)  { false }
+      let(:reblog) { true }
+
+      it 'not calls errors.add' do
+        expect(errors).not_to have_received(:add).with(:text, any_args)
+      end
+    end
+
+    context 'status.local? && !status.reblog?' do
+      let(:local)  { true }
+      let(:reblog) { false }
+
+      context 'tags.empty?' do
+        let(:tags) { [] }
+
+        it 'not calls errors.add' do
+          expect(errors).not_to have_received(:add).with(:text, any_args)
+        end
+      end
+
+      context '!tags.empty?' do
+        let(:tags) { %w(a b c) }
+
+        it 'calls errors.add' do
+          expect(errors).to have_received(:add)
+            .with(:text, I18n.t('statuses.disallowed_hashtags', tags: tags.join(', '), count: tags.size))
+        end
+      end
+    end
+  end
+end
diff --git a/spec/validators/email_mx_validator_spec.rb b/spec/validators/email_mx_validator_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bc68f63cfbc16fa3b22eb87e5d4e0e699f177b62
--- /dev/null
+++ b/spec/validators/email_mx_validator_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe EmailMxValidator do
+  describe '#validate' do
+    let(:user) { double(email: 'foo@example.com', errors: double(add: nil)) }
+
+    it 'adds an error if there are no DNS records for the e-mail domain' do
+      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(: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 a MX record exists but does not lead to an IP' do
+      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('mail.example.com', Resolv::DNS::Resource::IN::A).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 A record is blacklisted' do
+      EmailDomainBlock.create!(domain: '1.2.3.4')
+      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([double(address: '1.2.3.4')])
+      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 record is blacklisted' do
+      EmailDomainBlock.create!(domain: '2.3.4.5')
+      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('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '2.3.4.5')])
+      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 hostname is blacklisted' do
+      EmailDomainBlock.create!(domain: 'mail.example.com')
+      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('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '2.3.4.5')])
+      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
+  end
+end
diff --git a/spec/validators/follow_limit_validator_spec.rb b/spec/validators/follow_limit_validator_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cc8fbb6313233f920b7193bb395c633752455273
--- /dev/null
+++ b/spec/validators/follow_limit_validator_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe FollowLimitValidator, type: :validator do
+  describe '#validate' do
+    before do
+      allow_any_instance_of(described_class).to receive(:limit_reached?).with(account) do
+        limit_reached
+      end
+
+      described_class.new.validate(follow)
+    end
+
+    let(:follow)  { double(account: account, errors: errors) }
+    let(:errors)  { double(add: nil) }
+    let(:account) { double(nil?: _nil, local?: local, following_count: 0, followers_count: 0) }
+    let(:_nil)    { true }
+    let(:local)   { false }
+
+    context 'follow.account.nil? || !follow.account.local?' do
+      let(:_nil)    { true }
+
+      it 'not calls errors.add' do
+        expect(errors).not_to have_received(:add).with(:base, any_args)
+      end
+    end
+
+    context '!(follow.account.nil? || !follow.account.local?)' do
+      let(:_nil)    { false }
+      let(:local)   { true }
+
+      context 'limit_reached?' do
+        let(:limit_reached) { true }
+
+        it 'calls errors.add' do
+          expect(errors).to have_received(:add)
+            .with(:base, I18n.t('users.follow_limit_reached', limit: FollowLimitValidator::LIMIT))
+        end
+      end
+
+      context '!limit_reached?' do
+        let(:limit_reached) { false }
+
+        it 'not calls errors.add' do
+          expect(errors).not_to have_received(:add).with(:base, any_args)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/validators/status_length_validator_spec.rb b/spec/validators/status_length_validator_spec.rb
index e2d1a15ec96387954e66fdb07993144d1b66e649..11e55f9335f184e73a6d4a81c30de8974107db2e 100644
--- a/spec/validators/status_length_validator_spec.rb
+++ b/spec/validators/status_length_validator_spec.rb
@@ -4,8 +4,17 @@ require 'rails_helper'
 
 describe StatusLengthValidator do
   describe '#validate' do
-    it 'does not add errors onto remote statuses'
-    it 'does not add errors onto local reblogs'
+    it 'does not add errors onto remote statuses' do
+      status = double(local?: false)
+      subject.validate(status)
+      expect(status).not_to receive(:errors)
+    end
+
+    it 'does not add errors onto local reblogs' do
+      status = double(local?: false, reblog?: true)
+      subject.validate(status)
+      expect(status).not_to receive(:errors)
+    end
 
     it 'adds an error when content warning is over 500 characters' do
       status = double(spoiler_text: 'a' * 520, text: '', errors: double(add: nil), local?: true, reblog?: false)
diff --git a/spec/validators/status_pin_validator_spec.rb b/spec/validators/status_pin_validator_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..06532e5b3f5a701f3203fed142c2d05b8b678361
--- /dev/null
+++ b/spec/validators/status_pin_validator_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe StatusPinValidator, type: :validator do
+  describe '#validate' do
+    before do
+      subject.validate(pin)
+    end
+
+    let(:pin) { double(account: account, errors: errors, status: status, account_id: pin_account_id) }
+    let(:status) { double(reblog?: reblog, account_id: status_account_id, visibility: visibility) }
+    let(:account)     { double(status_pins: status_pins, local?: local) }
+    let(:status_pins) { double(count: count) }
+    let(:errors)      { double(add: nil) }
+    let(:pin_account_id)    { 1 }
+    let(:status_account_id) { 1 }
+    let(:visibility)  { 'public' }
+    let(:local)       { false }
+    let(:reblog)      { false }
+    let(:count)       { 0 }
+
+    context 'pin.status.reblog?' do
+      let(:reblog) { true }
+
+      it 'calls errors.add' do
+        expect(errors).to have_received(:add).with(:base, I18n.t('statuses.pin_errors.reblog'))
+      end
+    end
+
+    context 'pin.account_id != pin.status.account_id' do
+      let(:pin_account_id)    { 1 }
+      let(:status_account_id) { 2 }
+
+      it 'calls errors.add' do
+        expect(errors).to have_received(:add).with(:base, I18n.t('statuses.pin_errors.ownership'))
+      end
+    end
+
+    context 'unless %w(public unlisted).include?(pin.status.visibility)' do
+      let(:visibility) { '' }
+
+      it 'calls errors.add' do
+        expect(errors).to have_received(:add).with(:base, I18n.t('statuses.pin_errors.private'))
+      end
+    end
+
+    context 'pin.account.status_pins.count > 4 && pin.account.local?' do
+      let(:count) { 5 }
+      let(:local) { true }
+
+      it 'calls errors.add' do
+        expect(errors).to have_received(:add).with(:base, I18n.t('statuses.pin_errors.limit'))
+      end
+    end
+  end
+end
diff --git a/spec/validators/unique_username_validator_spec.rb b/spec/validators/unique_username_validator_spec.rb
index b9d773bed3bc1da46b9cc7a20f8ede99c7780eb1..c2e2eedf41f26c5b53dc623eca69eb3d1b23aafa 100644
--- a/spec/validators/unique_username_validator_spec.rb
+++ b/spec/validators/unique_username_validator_spec.rb
@@ -15,14 +15,6 @@ describe UniqueUsernameValidator do
       expect(account).to be_valid
     end
 
-    it 'adds an error when the username is already used with ignoring dots' do
-      pending 'allowing dots in username is still in development'
-      Fabricate(:account, username: 'abcd.ef')
-      account = double(username: 'ab.cdef', persisted?: false, errors: double(add: nil))
-      subject.validate(account)
-      expect(account.errors).to have_received(:add)
-    end
-
     it 'adds an error when the username is already used with ignoring cases' do
       Fabricate(:account, username: 'ABCdef')
       account = double(username: 'abcDEF', persisted?: false, errors: double(add: nil))
diff --git a/spec/validators/unreserved_username_validator_spec.rb b/spec/validators/unreserved_username_validator_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0187941b0378ce0b219741a1caf5f8d9b72a79c8
--- /dev/null
+++ b/spec/validators/unreserved_username_validator_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe UnreservedUsernameValidator, type: :validator do
+  describe '#validate' do
+    before do
+      allow(validator).to receive(:reserved_username?) { reserved_username }
+      validator.validate(account)
+    end
+
+    let(:validator) { described_class.new }
+    let(:account)   { double(username: username, errors: errors) }
+    let(:errors )   { double(add: nil) }
+
+    context '@username.nil?' do
+      let(:username)  { nil }
+
+      it 'not calls errors.add' do
+        expect(errors).not_to have_received(:add).with(:username, any_args)
+      end
+    end
+
+    context '!@username.nil?' do
+      let(:username)  { '' }
+
+      context 'reserved_username?' do
+        let(:reserved_username) { true }
+
+        it 'calls erros.add' do
+          expect(errors).to have_received(:add).with(:username, I18n.t('accounts.reserved_username'))
+        end
+      end
+
+      context '!reserved_username?' do
+        let(:reserved_username) { false }
+
+        it 'not calls erros.add' do
+          expect(errors).not_to have_received(:add).with(:username, any_args)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/validators/url_validator_spec.rb b/spec/validators/url_validator_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e8d0e6494690aceebc1c7c9bc6e297c6137f3af9
--- /dev/null
+++ b/spec/validators/url_validator_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe UrlValidator, type: :validator do
+  describe '#validate_each' do
+    before do
+      allow(validator).to receive(:compliant?).with(value) { compliant }
+      validator.validate_each(record, attribute, value)
+    end
+
+    let(:validator) { described_class.new(attributes: [attribute]) }
+    let(:record)    { double(errors: errors) }
+    let(:errors)    { double(add: nil) }
+    let(:value)     { '' }
+    let(:attribute) { :foo }
+
+    context 'unless compliant?' do
+      let(:compliant) { false }
+
+      it 'calls errors.add' do
+        expect(errors).to have_received(:add).with(attribute, I18n.t('applications.invalid_url'))
+      end
+    end
+
+    context 'if compliant?' do
+      let(:compliant) { true }
+
+      it 'not calls errors.add' do
+        expect(errors).not_to have_received(:add).with(attribute, any_args)
+      end
+    end
+  end
+end
diff --git a/spec/views/about/_contact.html.haml_spec.rb b/spec/views/about/_contact.html.haml_spec.rb
deleted file mode 100644
index 25ba1579464a3b74f4061b26ed0c6a9271c1539e..0000000000000000000000000000000000000000
--- a/spec/views/about/_contact.html.haml_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe 'about/_contact.html.haml' do
-  describe 'the contact account', without_verify_partial_doubles: true do
-    before do
-      allow(view).to receive(:display_name).and_return('Display Name!')
-    end
-
-    it 'shows info when account is present' do
-      account = Account.new(username: 'admin')
-      contact = double(contact_account: account, site_contact_email: '')
-      render 'about/contact', contact: contact
-
-      expect(rendered).to have_content('@admin')
-    end
-
-    it 'does not show info when account is missing' do
-      contact = double(contact_account: nil, site_contact_email: '')
-      render 'about/contact', contact: contact
-
-      expect(rendered).not_to have_content('@')
-    end
-  end
-
-  describe 'the contact email' do
-    it 'show info when email is present' do
-      contact = double(site_contact_email: 'admin@example.com', contact_account: nil)
-      render 'about/contact', contact: contact
-
-      expect(rendered).to have_content('admin@example.com')
-    end
-  end
-end
diff --git a/spec/views/about/show.html.haml_spec.rb b/spec/views/about/show.html.haml_spec.rb
index cbe5aa93b68923b0af6a4cc2958dcb147dd05ad5..eb81090b5173b2452f89bfcafa1db9d9918eea95 100644
--- a/spec/views/about/show.html.haml_spec.rb
+++ b/spec/views/about/show.html.haml_spec.rb
@@ -11,12 +11,14 @@ describe 'about/show.html.haml', without_verify_partial_doubles: true do
   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,
diff --git a/spec/views/stream_entries/show.html.haml_spec.rb b/spec/views/stream_entries/show.html.haml_spec.rb
index e0681b125779a4d8ed35c0ac0392f00cc9873e7c..93f0adb991c399082f7f34f8182117347352b8a0 100644
--- a/spec/views/stream_entries/show.html.haml_spec.rb
+++ b/spec/views/stream_entries/show.html.haml_spec.rb
@@ -12,6 +12,8 @@ describe 'stream_entries/show.html.haml', without_verify_partial_doubles: true d
     allow(view).to receive(:full_asset_url).and_return('//asset.host/image.svg')
     allow(view).to receive(:local_time)
     allow(view).to receive(:local_time_ago)
+    allow(view).to receive(:current_account).and_return(nil)
+    assign(:instance_presenter, InstancePresenter.new)
   end
 
   it 'has valid author h-card and basic data for a detailed_status' do
@@ -47,8 +49,8 @@ describe 'stream_entries/show.html.haml', without_verify_partial_doubles: true d
     assign(:stream_entry, reply.stream_entry)
     assign(:account, alice)
     assign(:type, reply.stream_entry.activity_type.downcase)
-    assign(:ancestors, reply.stream_entry.activity.ancestors(1, bob) )
-    assign(:descendant_threads, [{ statuses: reply.stream_entry.activity.descendants(1)}])
+    assign(:ancestors, reply.stream_entry.activity.ancestors(1, bob))
+    assign(:descendant_threads, [{ statuses: reply.stream_entry.activity.descendants(1) }])
 
     render
 
diff --git a/spec/workers/publish_scheduled_status_worker_spec.rb b/spec/workers/publish_scheduled_status_worker_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f8547e6fe2a6853b7ff458f998482225f3e3bbd0
--- /dev/null
+++ b/spec/workers/publish_scheduled_status_worker_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe PublishScheduledStatusWorker do
+  subject { described_class.new }
+
+  let(:scheduled_status) { Fabricate(:scheduled_status, params: { text: 'Hello world, future!' }) }
+
+  describe 'perform' do
+    before do
+      subject.perform(scheduled_status.id)
+    end
+
+    it 'creates a status' do
+      expect(scheduled_status.account.statuses.first.text).to eq 'Hello world, future!'
+    end
+
+    it 'removes the scheduled status' do
+      expect(ScheduledStatus.find_by(id: scheduled_status.id)).to be_nil
+    end
+  end
+end
diff --git a/streaming/index.js b/streaming/index.js
index 4eaf66865839a9f87ceca6de4849413fcd027349..b4d09d0ad2c7d60b0a0c7b1d74a7404a133d9a12 100644
--- a/streaming/index.js
+++ b/streaming/index.js
@@ -9,6 +9,7 @@ const log = require('npmlog');
 const url = require('url');
 const WebSocket = require('uws');
 const uuid = require('uuid');
+const fs = require('fs');
 
 const env = process.env.NODE_ENV || 'development';
 
@@ -70,6 +71,10 @@ const redisUrlToClient = (defaultConfig, redisUrl) => {
 const numWorkers = +process.env.STREAMING_CLUSTER_NUM || (env === 'development' ? 1 : Math.max(os.cpus().length - 1, 1));
 
 const startMaster = () => {
+  if (!process.env.SOCKET && process.env.PORT && isNaN(+process.env.PORT)) {
+    log.warn('UNIX domain socket is now supported by using SOCKET. Please migrate from PORT hack.');
+  }
+
   log.info(`Starting streaming API server master with ${numWorkers} workers`);
 };
 
@@ -192,7 +197,7 @@ const startWorker = (workerId) => {
         return;
       }
 
-      client.query('SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.filtered_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 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) {
@@ -209,7 +214,7 @@ const startWorker = (workerId) => {
         }
 
         req.accountId = result.rows[0].account_id;
-        req.filteredLanguages = result.rows[0].filtered_languages;
+        req.chosenLanguages = result.rows[0].chosen_languages;
 
         next();
       });
@@ -340,7 +345,7 @@ const startWorker = (workerId) => {
       const targetAccountIds = [unpackedPayload.account.id].concat(unpackedPayload.mentions.map(item => item.id));
       const accountDomain    = unpackedPayload.account.acct.split('@')[1];
 
-      if (Array.isArray(req.filteredLanguages) && req.filteredLanguages.indexOf(unpackedPayload.language) !== -1) {
+      if (Array.isArray(req.chosenLanguages) && unpackedPayload.language !== null && req.chosenLanguages.indexOf(unpackedPayload.language) === -1) {
         log.silly(req.requestId, `Message ${unpackedPayload.id} filtered by language (${unpackedPayload.language})`);
         return;
       }
@@ -445,9 +450,20 @@ const startWorker = (workerId) => {
     });
   };
 
+  const httpNotFound = res => {
+    res.writeHead(404, { 'Content-Type': 'application/json' });
+    res.end(JSON.stringify({ error: 'Not found' }));
+  };
+
   app.use(setRequestId);
   app.use(setRemoteAddress);
   app.use(allowCrossDomain);
+
+  app.get('/api/v1/streaming/health', (req, res) => {
+    res.writeHead(200, { 'Content-Type': 'text/plain' });
+    res.end('OK');
+  });
+
   app.use(authenticationMiddleware);
   app.use(errorMiddleware);
 
@@ -475,15 +491,30 @@ const startWorker = (workerId) => {
   });
 
   app.get('/api/v1/streaming/direct', (req, res) => {
-    streamFrom(`timeline:direct:${req.accountId}`, req, streamToHttp(req, res), streamHttpEnd(req), true);
+    const channel = `timeline:direct:${req.accountId}`;
+    streamFrom(channel, req, streamToHttp(req, res), streamHttpEnd(req, subscriptionHeartbeat(channel)), true);
   });
 
   app.get('/api/v1/streaming/hashtag', (req, res) => {
-    streamFrom(`timeline:hashtag:${req.query.tag.toLowerCase()}`, req, streamToHttp(req, res), streamHttpEnd(req), true);
+    const { tag } = req.query;
+
+    if (!tag || tag.length === 0) {
+      httpNotFound(res);
+      return;
+    }
+
+    streamFrom(`timeline:hashtag:${tag.toLowerCase()}`, req, streamToHttp(req, res), streamHttpEnd(req), true);
   });
 
   app.get('/api/v1/streaming/hashtag/local', (req, res) => {
-    streamFrom(`timeline:hashtag:${req.query.tag.toLowerCase()}:local`, req, streamToHttp(req, res), streamHttpEnd(req), true);
+    const { tag } = req.query;
+
+    if (!tag || tag.length === 0) {
+      httpNotFound(res);
+      return;
+    }
+
+    streamFrom(`timeline:hashtag:${tag.toLowerCase()}:local`, req, streamToHttp(req, res), streamHttpEnd(req), true);
   });
 
   app.get('/api/v1/streaming/list', (req, res) => {
@@ -491,8 +522,7 @@ const startWorker = (workerId) => {
 
     authorizeListAccess(listId, req, authorized => {
       if (!authorized) {
-        res.writeHead(404, { 'Content-Type': 'application/json' });
-        res.end(JSON.stringify({ error: 'Not found' }));
+        httpNotFound(res);
         return;
       }
 
@@ -515,9 +545,11 @@ const startWorker = (workerId) => {
       ws.isAlive = true;
     });
 
+    let channel;
+
     switch(location.query.stream) {
     case 'user':
-      const channel = `timeline:${req.accountId}`;
+      channel = `timeline:${req.accountId}`;
       streamFrom(channel, req, streamToWs(req, ws), streamWsEnd(req, ws, subscriptionHeartbeat(channel)));
       break;
     case 'user:notification':
@@ -536,12 +568,23 @@ const startWorker = (workerId) => {
       streamFrom('timeline:public:local:media', req, streamToWs(req, ws), streamWsEnd(req, ws), true);
       break;
     case 'direct':
-      streamFrom(`timeline:direct:${req.accountId}`, req, streamToWs(req, ws), streamWsEnd(req, ws), true);
+      channel = `timeline:direct:${req.accountId}`;
+      streamFrom(channel, req, streamToWs(req, ws), streamWsEnd(req, ws, subscriptionHeartbeat(channel)), true);
       break;
     case 'hashtag':
+      if (!location.query.tag || location.query.tag.length === 0) {
+        ws.close();
+        return;
+      }
+
       streamFrom(`timeline:hashtag:${location.query.tag.toLowerCase()}`, req, streamToWs(req, ws), streamWsEnd(req, ws), true);
       break;
     case 'hashtag:local':
+      if (!location.query.tag || location.query.tag.length === 0) {
+        ws.close();
+        return;
+      }
+
       streamFrom(`timeline:hashtag:${location.query.tag.toLowerCase()}:local`, req, streamToWs(req, ws), streamWsEnd(req, ws), true);
       break;
     case 'list':
@@ -553,7 +596,7 @@ const startWorker = (workerId) => {
           return;
         }
 
-        const channel = `timeline:list:${listId}`;
+        channel = `timeline:list:${listId}`;
         streamFrom(channel, req, streamToWs(req, ws), streamWsEnd(req, ws, subscriptionHeartbeat(channel)));
       });
       break;
@@ -574,8 +617,8 @@ const startWorker = (workerId) => {
     });
   }, 30000);
 
-  server.listen(process.env.PORT || 4000, process.env.BIND || '0.0.0.0', () => {
-    log.info(`Worker ${workerId} now listening on ${server.address().address}:${server.address().port}`);
+  attachServerWithConfig(server, address => {
+    log.info(`Worker ${workerId} now listening on ${address}`);
   });
 
   const onExit = () => {
@@ -596,9 +639,48 @@ const startWorker = (workerId) => {
   process.on('uncaughtException', onError);
 };
 
-throng({
-  workers: numWorkers,
-  lifetime: Infinity,
-  start: startWorker,
-  master: startMaster,
+const attachServerWithConfig = (server, onSuccess) => {
+  if (process.env.SOCKET || process.env.PORT && isNaN(+process.env.PORT)) {
+    server.listen(process.env.SOCKET || process.env.PORT, () => {
+      if (onSuccess) {
+        fs.chmodSync(server.address(), 0o666);
+        onSuccess(server.address());
+      }
+    });
+  } else {
+    server.listen(+process.env.PORT || 4000, process.env.BIND || '0.0.0.0', () => {
+      if (onSuccess) {
+        onSuccess(`${server.address().address}:${server.address().port}`);
+      }
+    });
+  }
+};
+
+const onPortAvailable = onSuccess => {
+  const testServer = http.createServer();
+
+  testServer.once('error', err => {
+    onSuccess(err);
+  });
+
+  testServer.once('listening', () => {
+    testServer.once('close', () => onSuccess());
+    testServer.close();
+  });
+
+  attachServerWithConfig(testServer);
+};
+
+onPortAvailable(err => {
+  if (err) {
+    log.error('Could not start server, the port or socket is in use');
+    return;
+  }
+
+  throng({
+    workers: numWorkers,
+    lifetime: Infinity,
+    start: startWorker,
+    master: startMaster,
+  });
 });
diff --git a/vendor/assets/javascripts/.keep b/vendor/.keep
similarity index 100%
rename from vendor/assets/javascripts/.keep
rename to vendor/.keep
diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/yarn.lock b/yarn.lock
index 64183514976768ac1f674f6996bbaa752dfe495c..9ff12a712bfa077c87d21109b719d9a09f78ccc7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,1119 +2,1484 @@
 # yarn lockfile v1
 
 
-"@babel/code-frame@7.0.0-beta.36":
-  version "7.0.0-beta.36"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.36.tgz#2349d7ec04b3a06945ae173280ef8579b63728e4"
-  dependencies:
-    chalk "^2.0.0"
-    esutils "^2.0.2"
-    js-tokens "^3.0.0"
-
-"@babel/code-frame@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9"
-  dependencies:
-    "@babel/highlight" "7.0.0-beta.44"
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35":
+  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==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@babel/generator" "^7.2.2"
+    "@babel/helpers" "^7.2.0"
+    "@babel/parser" "^7.2.2"
+    "@babel/template" "^7.2.2"
+    "@babel/traverse" "^7.2.2"
+    "@babel/types" "^7.2.2"
+    convert-source-map "^1.1.0"
+    debug "^4.1.0"
+    json5 "^2.1.0"
+    lodash "^4.17.10"
+    resolve "^1.3.2"
+    semver "^5.4.1"
+    source-map "^0.5.0"
 
-"@babel/generator@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42"
+"@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==
   dependencies:
-    "@babel/types" "7.0.0-beta.44"
+    "@babel/types" "^7.2.2"
     jsesc "^2.5.1"
-    lodash "^4.2.0"
+    lodash "^4.17.10"
     source-map "^0.5.0"
     trim-right "^1.0.1"
 
-"@babel/helper-function-name@7.0.0-beta.36":
-  version "7.0.0-beta.36"
-  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.36.tgz#366e3bc35147721b69009f803907c4d53212e88d"
+"@babel/helper-annotate-as-pure@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
+  integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==
   dependencies:
-    "@babel/helper-get-function-arity" "7.0.0-beta.36"
-    "@babel/template" "7.0.0-beta.36"
-    "@babel/types" "7.0.0-beta.36"
+    "@babel/types" "^7.0.0"
 
-"@babel/helper-function-name@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd"
+"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0":
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f"
+  integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==
   dependencies:
-    "@babel/helper-get-function-arity" "7.0.0-beta.44"
-    "@babel/template" "7.0.0-beta.44"
-    "@babel/types" "7.0.0-beta.44"
+    "@babel/helper-explode-assignable-expression" "^7.1.0"
+    "@babel/types" "^7.0.0"
 
-"@babel/helper-get-function-arity@7.0.0-beta.36":
-  version "7.0.0-beta.36"
-  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.36.tgz#f5383bac9a96b274828b10d98900e84ee43e32b8"
+"@babel/helper-builder-react-jsx@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz#fa154cb53eb918cf2a9a7ce928e29eb649c5acdb"
+  integrity sha512-ebJ2JM6NAKW0fQEqN8hOLxK84RbRz9OkUhGS/Xd5u56ejMfVbayJ4+LykERZCOUM6faa6Fp3SZNX3fcT16MKHw==
   dependencies:
-    "@babel/types" "7.0.0-beta.36"
+    "@babel/types" "^7.0.0"
+    esutils "^2.0.0"
 
-"@babel/helper-get-function-arity@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15"
+"@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==
   dependencies:
-    "@babel/types" "7.0.0-beta.44"
+    "@babel/helper-hoist-variables" "^7.0.0"
+    "@babel/traverse" "^7.1.0"
+    "@babel/types" "^7.0.0"
 
-"@babel/helper-split-export-declaration@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc"
+"@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==
   dependencies:
-    "@babel/types" "7.0.0-beta.44"
+    "@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/highlight@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5"
+"@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==
   dependencies:
-    chalk "^2.0.0"
-    esutils "^2.0.2"
-    js-tokens "^3.0.0"
-
-"@babel/template@7.0.0-beta.36":
-  version "7.0.0-beta.36"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.36.tgz#02e903de5d68bd7899bce3c5b5447e59529abb00"
-  dependencies:
-    "@babel/code-frame" "7.0.0-beta.36"
-    "@babel/types" "7.0.0-beta.36"
-    babylon "7.0.0-beta.36"
-    lodash "^4.2.0"
-
-"@babel/template@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f"
-  dependencies:
-    "@babel/code-frame" "7.0.0-beta.44"
-    "@babel/types" "7.0.0-beta.44"
-    babylon "7.0.0-beta.44"
-    lodash "^4.2.0"
-
-"@babel/traverse@7.0.0-beta.36":
-  version "7.0.0-beta.36"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.36.tgz#1dc6f8750e89b6b979de5fe44aa993b1a2192261"
-  dependencies:
-    "@babel/code-frame" "7.0.0-beta.36"
-    "@babel/helper-function-name" "7.0.0-beta.36"
-    "@babel/types" "7.0.0-beta.36"
-    babylon "7.0.0-beta.36"
-    debug "^3.0.1"
-    globals "^11.1.0"
-    invariant "^2.2.0"
-    lodash "^4.2.0"
-
-"@babel/traverse@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966"
-  dependencies:
-    "@babel/code-frame" "7.0.0-beta.44"
-    "@babel/generator" "7.0.0-beta.44"
-    "@babel/helper-function-name" "7.0.0-beta.44"
-    "@babel/helper-split-export-declaration" "7.0.0-beta.44"
-    "@babel/types" "7.0.0-beta.44"
-    babylon "7.0.0-beta.44"
-    debug "^3.1.0"
-    globals "^11.1.0"
-    invariant "^2.2.0"
-    lodash "^4.2.0"
+    "@babel/helper-function-name" "^7.1.0"
+    "@babel/types" "^7.0.0"
+    lodash "^4.17.10"
 
-"@babel/types@7.0.0-beta.36":
-  version "7.0.0-beta.36"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.36.tgz#64f2004353de42adb72f9ebb4665fc35b5499d23"
+"@babel/helper-explode-assignable-expression@^7.1.0":
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6"
+  integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==
   dependencies:
-    esutils "^2.0.2"
-    lodash "^4.2.0"
-    to-fast-properties "^2.0.0"
+    "@babel/traverse" "^7.1.0"
+    "@babel/types" "^7.0.0"
 
-"@babel/types@7.0.0-beta.44":
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757"
+"@babel/helper-function-name@^7.1.0":
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53"
+  integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==
   dependencies:
-    esutils "^2.0.2"
-    lodash "^4.2.0"
-    to-fast-properties "^2.0.0"
+    "@babel/helper-get-function-arity" "^7.0.0"
+    "@babel/template" "^7.1.0"
+    "@babel/types" "^7.0.0"
 
-"@types/node@*":
-  version "8.0.53"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8"
-
-abab@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
-
-abbrev@1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
+"@babel/helper-get-function-arity@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3"
+  integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==
+  dependencies:
+    "@babel/types" "^7.0.0"
 
-accepts@~1.3.4:
-  version "1.3.4"
-  resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f"
+"@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==
   dependencies:
-    mime-types "~2.1.16"
-    negotiator "0.6.1"
+    "@babel/types" "^7.0.0"
 
-acorn-dynamic-import@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4"
+"@babel/helper-member-expression-to-functions@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f"
+  integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==
   dependencies:
-    acorn "^4.0.3"
+    "@babel/types" "^7.0.0"
 
-acorn-globals@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf"
+"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d"
+  integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==
   dependencies:
-    acorn "^4.0.4"
+    "@babel/types" "^7.0.0"
 
-acorn-jsx@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
+"@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==
   dependencies:
-    acorn "^3.0.4"
+    "@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"
 
-acorn@^3.0.4:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
+"@babel/helper-optimise-call-expression@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5"
+  integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==
+  dependencies:
+    "@babel/types" "^7.0.0"
 
-acorn@^4.0.3, acorn@^4.0.4:
-  version "4.0.13"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
+"@babel/helper-plugin-utils@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250"
+  integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==
 
-acorn@^5.0.0, acorn@^5.1.1:
-  version "5.2.1"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7"
+"@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==
+  dependencies:
+    lodash "^4.17.10"
 
-acorn@^5.5.0:
-  version "5.6.0"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.6.0.tgz#572bedb377a1c61b7a289e72b8c5cfeb7baaf0bf"
+"@babel/helper-remap-async-to-generator@^7.1.0":
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f"
+  integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.0.0"
+    "@babel/helper-wrap-function" "^7.1.0"
+    "@babel/template" "^7.1.0"
+    "@babel/traverse" "^7.1.0"
+    "@babel/types" "^7.0.0"
 
-adjust-sourcemap-loader@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.1.0.tgz#412d92404eb61e4113635012cba53a33d008e0e2"
+"@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==
   dependencies:
-    assert "^1.3.0"
-    camelcase "^1.2.1"
-    loader-utils "^1.0.2"
-    lodash.assign "^4.0.1"
-    lodash.defaults "^3.1.2"
-    object-path "^0.9.2"
-    regex-parser "^2.2.1"
+    "@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"
 
-ajv-keywords@^2.0.0, ajv-keywords@^2.1.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
+"@babel/helper-simple-access@^7.1.0":
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c"
+  integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==
+  dependencies:
+    "@babel/template" "^7.1.0"
+    "@babel/types" "^7.0.0"
 
-ajv@^4.9.1:
-  version "4.11.8"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
+"@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==
   dependencies:
-    co "^4.6.0"
-    json-stable-stringify "^1.0.1"
+    "@babel/types" "^7.0.0"
 
-ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5:
-  version "5.5.1"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2"
+"@babel/helper-wrap-function@^7.1.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa"
+  integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==
   dependencies:
-    co "^4.6.0"
-    fast-deep-equal "^1.0.0"
-    fast-json-stable-stringify "^2.0.0"
-    json-schema-traverse "^0.3.0"
+    "@babel/helper-function-name" "^7.1.0"
+    "@babel/template" "^7.1.0"
+    "@babel/traverse" "^7.1.0"
+    "@babel/types" "^7.2.0"
 
-ajv@^5.2.3, ajv@^5.3.0:
-  version "5.5.2"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
+"@babel/helpers@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.2.0.tgz#8335f3140f3144270dc63c4732a4f8b0a50b7a21"
+  integrity sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A==
   dependencies:
-    co "^4.6.0"
-    fast-deep-equal "^1.0.0"
-    fast-json-stable-stringify "^2.0.0"
-    json-schema-traverse "^0.3.0"
+    "@babel/template" "^7.1.2"
+    "@babel/traverse" "^7.1.5"
+    "@babel/types" "^7.2.0"
 
-align-text@^0.1.1, align-text@^0.1.3:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
+"@babel/highlight@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
+  integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==
   dependencies:
-    kind-of "^3.0.2"
-    longest "^1.0.1"
-    repeat-string "^1.5.2"
+    chalk "^2.0.0"
+    esutils "^2.0.2"
+    js-tokens "^4.0.0"
 
-alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
+"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3":
+  version "7.2.3"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.3.tgz#32f5df65744b70888d17872ec106b02434ba1489"
+  integrity sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==
 
-amdefine@>=0.0.4:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
+"@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"
+  integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/helper-remap-async-to-generator" "^7.1.0"
+    "@babel/plugin-syntax-async-generators" "^7.2.0"
 
-ansi-escapes@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92"
+"@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==
+  dependencies:
+    "@babel/helper-create-class-features-plugin" "^7.2.3"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-ansi-html@0.0.7:
-  version "0.0.7"
-  resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e"
+"@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==
+  dependencies:
+    "@babel/helper-create-class-features-plugin" "^7.2.3"
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-syntax-decorators" "^7.2.0"
 
-ansi-regex@^2.0.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+"@babel/plugin-proposal-json-strings@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317"
+  integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-syntax-json-strings" "^7.2.0"
 
-ansi-regex@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
+"@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==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
 
-ansi-styles@^2.2.1:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+"@babel/plugin-proposal-optional-catch-binding@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5"
+  integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
 
-ansi-styles@^3.1.0, ansi-styles@^3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
+"@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==
   dependencies:
-    color-convert "^1.9.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/helper-regex" "^7.0.0"
+    regexpu-core "^4.2.0"
 
-any-promise@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-0.1.0.tgz#830b680aa7e56f33451d4b049f3bd8044498ee27"
+"@babel/plugin-syntax-async-generators@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f"
+  integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-anymatch@^1.3.0:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
+"@babel/plugin-syntax-decorators@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz#c50b1b957dcc69e4b1127b65e1c33eef61570c1b"
+  integrity sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==
   dependencies:
-    micromatch "^2.1.5"
-    normalize-path "^2.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-append-transform@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991"
+"@babel/plugin-syntax-dynamic-import@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612"
+  integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==
   dependencies:
-    default-require-extensions "^1.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-aproba@^1.0.3:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
+"@babel/plugin-syntax-json-strings@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470"
+  integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-are-we-there-yet@~1.1.2:
-  version "1.1.4"
-  resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d"
+"@babel/plugin-syntax-jsx@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7"
+  integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==
   dependencies:
-    delegates "^1.0.0"
-    readable-stream "^2.0.6"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-argparse@^1.0.7:
-  version "1.0.9"
-  resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
+"@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==
   dependencies:
-    sprintf-js "~1.0.2"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-aria-query@^0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.7.0.tgz#4af10a1e61573ddea0cf3b99b51c52c05b424d24"
+"@babel/plugin-syntax-optional-catch-binding@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c"
+  integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==
   dependencies:
-    ast-types-flow "0.0.7"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-arr-diff@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
+"@babel/plugin-transform-arrow-functions@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550"
+  integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==
   dependencies:
-    arr-flatten "^1.0.1"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-arr-flatten@^1.0.1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
+"@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==
+  dependencies:
+    "@babel/helper-module-imports" "^7.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/helper-remap-async-to-generator" "^7.1.0"
 
-array-equal@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
+"@babel/plugin-transform-block-scoped-functions@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190"
+  integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-array-filter@~0.0.0:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
+"@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==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    lodash "^4.17.10"
 
-array-find-index@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
+"@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==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.0.0"
+    "@babel/helper-define-map" "^7.1.0"
+    "@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"
+    globals "^11.1.0"
 
-array-flatten@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
+"@babel/plugin-transform-computed-properties@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da"
+  integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-array-flatten@^2.1.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296"
+"@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==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-array-includes@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d"
+"@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==
   dependencies:
-    define-properties "^1.1.2"
-    es-abstract "^1.7.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/helper-regex" "^7.0.0"
+    regexpu-core "^4.1.3"
 
-array-map@~0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
+"@babel/plugin-transform-duplicate-keys@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3"
+  integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-array-reduce@~0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
+"@babel/plugin-transform-exponentiation-operator@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008"
+  integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==
+  dependencies:
+    "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-array-union@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+"@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==
   dependencies:
-    array-uniq "^1.0.1"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-array-uniq@^1.0.1:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+"@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==
+  dependencies:
+    "@babel/helper-function-name" "^7.1.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-array-unique@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
+"@babel/plugin-transform-literals@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1"
+  integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-arrify@^1.0.0, arrify@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+"@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"
+  integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==
+  dependencies:
+    "@babel/helper-module-transforms" "^7.1.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-asap@~2.0.3:
-  version "2.0.6"
-  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+"@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==
+  dependencies:
+    "@babel/helper-module-transforms" "^7.1.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/helper-simple-access" "^7.1.0"
 
-asn1.js@^4.0.0:
-  version "4.9.2"
-  resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a"
+"@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==
   dependencies:
-    bn.js "^4.0.0"
-    inherits "^2.0.1"
-    minimalistic-assert "^1.0.0"
+    "@babel/helper-hoist-variables" "^7.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-asn1@~0.2.3:
-  version "0.2.3"
-  resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+"@babel/plugin-transform-modules-umd@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae"
+  integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==
+  dependencies:
+    "@babel/helper-module-transforms" "^7.1.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-assert-plus@1.0.0, assert-plus@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+"@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==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-assert-plus@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
+"@babel/plugin-transform-object-super@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598"
+  integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/helper-replace-supers" "^7.1.0"
 
-assert@^1.1.1, assert@^1.3.0:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91"
+"@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==
   dependencies:
-    util "0.10.3"
+    "@babel/helper-call-delegate" "^7.1.0"
+    "@babel/helper-get-function-arity" "^7.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-ast-types-flow@0.0.7:
-  version "0.0.7"
-  resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
+"@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"
+  integrity sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-astral-regex@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
+"@babel/plugin-transform-react-inline-elements@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-inline-elements/-/plugin-transform-react-inline-elements-7.2.0.tgz#3e36e7c47f1c21f52b2b0090d5cd83ceb19a4770"
+  integrity sha512-OAflI+josEl8xoAzZYpFnN+C4e9wvxDecExTtvDsteAcChIZtsH/D2kMNcJnrrzbFzCroGajCTr9tAB7K0KsiQ==
+  dependencies:
+    "@babel/helper-builder-react-jsx" "^7.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-async-each@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
+"@babel/plugin-transform-react-jsx-self@^7.0.0", "@babel/plugin-transform-react-jsx-self@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz#461e21ad9478f1031dd5e276108d027f1b5240ba"
+  integrity sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-syntax-jsx" "^7.2.0"
 
-async-foreach@^0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542"
+"@babel/plugin-transform-react-jsx-source@^7.0.0", "@babel/plugin-transform-react-jsx-source@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz#20c8c60f0140f5dd3cd63418d452801cf3f7180f"
+  integrity sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-syntax-jsx" "^7.2.0"
 
-async-limiter@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
+"@babel/plugin-transform-react-jsx@^7.0.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.2.0.tgz#ca36b6561c4d3b45524f8efb6f0fbc9a0d1d622f"
+  integrity sha512-h/fZRel5wAfCqcKgq3OhbmYaReo7KkoJBpt8XnvpS7wqaNMqtw5xhxutzcm35iMUWucfAdT/nvGTsWln0JTg2Q==
+  dependencies:
+    "@babel/helper-builder-react-jsx" "^7.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-syntax-jsx" "^7.2.0"
 
-async@2.4.1:
-  version "2.4.1"
-  resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7"
+"@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==
   dependencies:
-    lodash "^4.14.0"
+    regenerator-transform "^0.13.3"
 
-async@^1.4.0, async@^1.5.2:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
+"@babel/plugin-transform-runtime@^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==
+  dependencies:
+    "@babel/helper-module-imports" "^7.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
+    resolve "^1.8.1"
+    semver "^5.5.1"
 
-async@^2.1.2, async@^2.1.4, async@^2.1.5, async@^2.4.1:
-  version "2.6.0"
-  resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
+"@babel/plugin-transform-shorthand-properties@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0"
+  integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==
   dependencies:
-    lodash "^4.14.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-asynckit@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+"@babel/plugin-transform-spread@^7.2.0":
+  version "7.2.2"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406"
+  integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-atob@~1.1.0:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773"
+"@babel/plugin-transform-sticky-regex@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1"
+  integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/helper-regex" "^7.0.0"
 
-autoprefixer@^6.3.1:
-  version "6.7.7"
-  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014"
+"@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==
   dependencies:
-    browserslist "^1.7.6"
-    caniuse-db "^1.0.30000634"
-    normalize-range "^0.1.2"
-    num2fraction "^1.2.2"
-    postcss "^5.2.16"
-    postcss-value-parser "^3.2.3"
+    "@babel/helper-annotate-as-pure" "^7.0.0"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-autoprefixer@^7.1.6:
-  version "7.1.6"
-  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.6.tgz#fb933039f74af74a83e71225ce78d9fd58ba84d7"
+"@babel/plugin-transform-typeof-symbol@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2"
+  integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==
   dependencies:
-    browserslist "^2.5.1"
-    caniuse-lite "^1.0.30000748"
-    normalize-range "^0.1.2"
-    num2fraction "^1.2.2"
-    postcss "^6.0.13"
-    postcss-value-parser "^3.2.3"
+    "@babel/helper-plugin-utils" "^7.0.0"
 
-aws-sign2@~0.6.0:
-  version "0.6.0"
-  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+"@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==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/helper-regex" "^7.0.0"
+    regexpu-core "^4.1.3"
 
-aws-sign2@~0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+"@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==
+  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-optional-catch-binding" "^7.2.0"
+    "@babel/plugin-proposal-unicode-property-regex" "^7.2.0"
+    "@babel/plugin-syntax-async-generators" "^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-block-scoped-functions" "^7.2.0"
+    "@babel/plugin-transform-block-scoping" "^7.2.0"
+    "@babel/plugin-transform-classes" "^7.2.0"
+    "@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-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-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-umd" "^7.2.0"
+    "@babel/plugin-transform-new-target" "^7.0.0"
+    "@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-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-typeof-symbol" "^7.2.0"
+    "@babel/plugin-transform-unicode-regex" "^7.2.0"
+    browserslist "^4.3.4"
+    invariant "^2.2.2"
+    js-levenshtein "^1.1.3"
+    semver "^5.3.0"
 
-aws4@^1.2.1, aws4@^1.6.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+"@babel/preset-react@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0"
+  integrity sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-transform-react-display-name" "^7.0.0"
+    "@babel/plugin-transform-react-jsx" "^7.0.0"
+    "@babel/plugin-transform-react-jsx-self" "^7.0.0"
+    "@babel/plugin-transform-react-jsx-source" "^7.0.0"
 
-axios@~0.16.2:
-  version "0.16.2"
-  resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d"
+"@babel/runtime@7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c"
+  integrity sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==
   dependencies:
-    follow-redirects "^1.2.3"
-    is-buffer "^1.1.5"
+    regenerator-runtime "^0.12.0"
 
-axobject-query@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-0.1.0.tgz#62f59dbc59c9f9242759ca349960e7a2fe3c36c0"
+"@babel/runtime@7.2.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@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:
-    ast-types-flow "0.0.7"
+    regenerator-runtime "^0.12.0"
 
-babel-code-frame@^6.11.0, babel-code-frame@^6.22.0, 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"
+"@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2":
+  version "7.2.2"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907"
+  integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@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":
+  version "7.2.3"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8"
+  integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@babel/generator" "^7.2.2"
+    "@babel/helper-function-name" "^7.1.0"
+    "@babel/helper-split-export-declaration" "^7.0.0"
+    "@babel/parser" "^7.2.3"
+    "@babel/types" "^7.2.2"
+    debug "^4.1.0"
+    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":
+  version "7.2.2"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e"
+  integrity sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==
   dependencies:
-    chalk "^1.1.3"
     esutils "^2.0.2"
-    js-tokens "^3.0.2"
+    lodash "^4.17.10"
+    to-fast-properties "^2.0.0"
 
-babel-core@^6.0.0, babel-core@^6.25.0, babel-core@^6.26.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8"
+"@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==
   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.0"
-    debug "^2.6.8"
-    json5 "^0.5.1"
-    lodash "^4.17.4"
-    minimatch "^3.0.4"
-    path-is-absolute "^1.0.1"
-    private "^0.1.7"
-    slash "^1.0.0"
-    source-map "^0.5.6"
+    "@emotion/sheet" "0.9.2"
+    "@emotion/stylis" "0.8.3"
+    "@emotion/utils" "0.11.1"
+    "@emotion/weak-memoize" "0.2.2"
 
-babel-eslint@^8.0.1:
-  version "8.2.1"
-  resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.1.tgz#136888f3c109edc65376c23ebf494f36a3e03951"
-  dependencies:
-    "@babel/code-frame" "7.0.0-beta.36"
-    "@babel/traverse" "7.0.0-beta.36"
-    "@babel/types" "7.0.0-beta.36"
-    babylon "7.0.0-beta.36"
-    eslint-scope "~3.7.1"
-    eslint-visitor-keys "^1.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==
 
-babel-eslint@^8.2.3:
-  version "8.2.3"
-  resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.3.tgz#1a2e6681cc9bc4473c32899e59915e19cd6733cf"
-  dependencies:
-    "@babel/code-frame" "7.0.0-beta.44"
-    "@babel/traverse" "7.0.0-beta.44"
-    "@babel/types" "7.0.0-beta.44"
-    babylon "7.0.0-beta.44"
-    eslint-scope "~3.7.1"
-    eslint-visitor-keys "^1.0.0"
+"@emotion/memoize@0.7.1":
+  version "0.7.1"
+  resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f"
+  integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==
 
-babel-generator@^6.18.0, babel-generator@^6.26.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5"
+"@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:
-    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.6"
-    trim-right "^1.0.1"
+    "@emotion/hash" "0.7.1"
+    "@emotion/memoize" "0.7.1"
+    "@emotion/unitless" "0.7.3"
+    "@emotion/utils" "0.11.1"
+    csstype "^2.5.7"
 
-babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664"
-  dependencies:
-    babel-helper-explode-assignable-expression "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+"@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==
 
-babel-helper-builder-react-jsx@^6.24.1:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0"
-  dependencies:
-    babel-runtime "^6.26.0"
-    babel-types "^6.26.0"
-    esutils "^2.0.2"
+"@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==
 
-babel-helper-call-delegate@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d"
-  dependencies:
-    babel-helper-hoist-variables "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-traverse "^6.24.1"
-    babel-types "^6.24.1"
+"@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==
 
-babel-helper-define-map@^6.24.1:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f"
-  dependencies:
-    babel-helper-function-name "^6.24.1"
-    babel-runtime "^6.26.0"
-    babel-types "^6.26.0"
-    lodash "^4.17.4"
+"@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==
 
-babel-helper-explode-assignable-expression@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa"
-  dependencies:
-    babel-runtime "^6.22.0"
-    babel-traverse "^6.24.1"
-    babel-types "^6.24.1"
+"@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==
 
-babel-helper-function-name@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
+"@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==
   dependencies:
-    babel-helper-get-function-arity "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
-    babel-traverse "^6.24.1"
-    babel-types "^6.24.1"
+    base64-js "^1.3.0"
 
-babel-helper-get-function-arity@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
-  dependencies:
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+"@types/node@*":
+  version "10.12.18"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
+  integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==
 
-babel-helper-hoist-variables@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76"
-  dependencies:
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+"@types/q@^1.5.1":
+  version "1.5.1"
+  resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18"
+  integrity sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==
+
+"@types/react@16.4.6":
+  version "16.4.6"
+  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.6.tgz#5024957c6bcef4f02823accf5974faba2e54fada"
+  integrity sha512-9LDZdhsuKSc+DjY65SjBkA958oBWcTWSVWAd2cD9XqKBjhGw1KzAkRhWRw2eIsXvaIE/TOTjjKMFVC+JA1iU4g==
+  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==
+  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"
+
+"@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==
 
-babel-helper-module-imports@^7.0.0-beta.3:
-  version "7.0.0-beta.3"
-  resolved "https://registry.yarnpkg.com/babel-helper-module-imports/-/babel-helper-module-imports-7.0.0-beta.3.tgz#e15764e3af9c8e11810c09f78f498a2bdc71585a"
-  dependencies:
-    babel-types "7.0.0-beta.3"
-    lodash "^4.2.0"
+"@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==
 
-babel-helper-optimise-call-expression@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257"
-  dependencies:
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+abab@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f"
+  integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==
 
-babel-helper-regex@^6.24.1:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72"
-  dependencies:
-    babel-runtime "^6.26.0"
-    babel-types "^6.26.0"
-    lodash "^4.17.4"
+abbrev@1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
+  integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
 
-babel-helper-remap-async-to-generator@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b"
+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=
   dependencies:
-    babel-helper-function-name "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
-    babel-traverse "^6.24.1"
-    babel-types "^6.24.1"
+    mime-types "~2.1.18"
+    negotiator "0.6.1"
 
-babel-helper-replace-supers@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a"
+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:
-    babel-helper-optimise-call-expression "^6.24.1"
-    babel-messages "^6.23.0"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
-    babel-traverse "^6.24.1"
-    babel-types "^6.24.1"
+    acorn "^5.0.0"
 
-babel-helpers@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
+acorn-globals@^4.1.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103"
+  integrity sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==
   dependencies:
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
+    acorn "^6.0.1"
+    acorn-walk "^6.0.1"
 
-babel-jest@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-21.2.0.tgz#2ce059519a9374a2c46f2455b6fbef5ad75d863e"
-  dependencies:
-    babel-plugin-istanbul "^4.0.0"
-    babel-preset-jest "^21.2.0"
+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==
 
-babel-loader@^7.1.1:
-  version "7.1.2"
-  resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.2.tgz#f6cbe122710f1aa2af4d881c6d5b54358ca24126"
-  dependencies:
-    find-cache-dir "^1.0.0"
-    loader-utils "^1.0.2"
-    mkdirp "^0.5.1"
+acorn-walk@^6.0.1:
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913"
+  integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==
 
-babel-macros@^1.1.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/babel-macros/-/babel-macros-1.2.0.tgz#39e47ed6d286d4a98f1948d8bab45dac17e4e2d4"
+acorn@^5.0.0, acorn@^5.5.3, acorn@^5.6.2, acorn@^5.7.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==
+
+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@^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@^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"
+  integrity sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==
   dependencies:
-    cosmiconfig "3.1.0"
+    fast-deep-equal "^2.0.1"
+    fast-json-stable-stringify "^2.0.0"
+    json-schema-traverse "^0.4.1"
+    uri-js "^4.2.2"
 
-babel-messages@^6.23.0:
-  version "6.23.0"
-  resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
+alphanum-sort@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
+  integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=
+
+ansi-colors@^3.0.0:
+  version "3.2.3"
+  resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813"
+  integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==
+
+ansi-escapes@^3.0.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
+  integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==
+
+ansi-html@0.0.7:
+  version "0.0.7"
+  resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e"
+  integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4=
+
+ansi-regex@^2.0.0:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+  integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
+
+ansi-regex@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
+  integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
+
+ansi-regex@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9"
+  integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==
+
+ansi-styles@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+  integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
+
+ansi-styles@^3.2.0, ansi-styles@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+  integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
   dependencies:
-    babel-runtime "^6.22.0"
+    color-convert "^1.9.0"
 
-babel-plugin-check-es2015-constants@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a"
+anymatch@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
+  integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==
   dependencies:
-    babel-runtime "^6.22.0"
+    micromatch "^3.1.4"
+    normalize-path "^2.1.1"
 
-babel-plugin-istanbul@^4.0.0:
-  version "4.1.5"
-  resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz#6760cdd977f411d3e175bb064f2bc327d99b2b6e"
+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:
-    find-up "^2.1.0"
-    istanbul-lib-instrument "^1.7.5"
-    test-exclude "^4.1.1"
+    default-require-extensions "^1.0.0"
 
-babel-plugin-jest-hoist@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz#2cef637259bd4b628a6cace039de5fcd14dbb006"
+aproba@^1.0.3, aproba@^1.1.1:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
+  integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
 
-babel-plugin-lodash@^3.3.2:
-  version "3.3.2"
-  resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.2.tgz#da3a5b49ba27447f54463f6c4fa81396ccdd463f"
+are-we-there-yet@~1.1.2:
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
+  integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
   dependencies:
-    babel-helper-module-imports "^7.0.0-beta.3"
-    babel-types "^6.26.0"
-    glob "^7.1.1"
-    lodash "^4.17.4"
-    require-package-name "^2.0.1"
+    delegates "^1.0.0"
+    readable-stream "^2.0.6"
 
-babel-plugin-preval@^1.6.1:
-  version "1.6.2"
-  resolved "https://registry.yarnpkg.com/babel-plugin-preval/-/babel-plugin-preval-1.6.2.tgz#8f580a1d4579d5fc79f1cfaee6f9fe0996fdeb1f"
+argparse@^1.0.7:
+  version "1.0.10"
+  resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
+  integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
   dependencies:
-    babel-macros "^1.1.1"
-    babel-register "^6.26.0"
-    babylon "^6.18.0"
-    require-from-string "^2.0.1"
+    sprintf-js "~1.0.2"
 
-babel-plugin-react-intl@^2.3.1:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-2.3.1.tgz#3d43912e824da005e08e8e8239d5ba784374bb00"
+aria-query@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc"
+  integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=
   dependencies:
-    babel-runtime "^6.2.0"
-    intl-messageformat-parser "^1.2.0"
-    mkdirp "^0.5.1"
-
-babel-plugin-syntax-async-functions@^6.8.0:
-  version "6.13.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
-
-babel-plugin-syntax-class-properties@^6.8.0:
-  version "6.13.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
+    ast-types-flow "0.0.7"
+    commander "^2.11.0"
 
-babel-plugin-syntax-decorators@^6.1.18:
-  version "6.13.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b"
+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"
 
-babel-plugin-syntax-dynamic-import@^6.18.0:
-  version "6.18.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
+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=
 
-babel-plugin-syntax-exponentiation-operator@^6.8.0:
-  version "6.13.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
+arr-flatten@^1.0.1, 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==
 
-babel-plugin-syntax-flow@^6.18.0:
-  version "6.18.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
+arr-union@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
+  integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
 
-babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0:
-  version "6.18.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
+array-equal@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
+  integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
 
-babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.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"
+array-flatten@1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
+  integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
 
-babel-plugin-syntax-trailing-function-commas@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
+array-flatten@^2.1.0:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
+  integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
 
-babel-plugin-transform-async-to-generator@^6.22.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761"
+array-includes@^3.0.3:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d"
+  integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=
   dependencies:
-    babel-helper-remap-async-to-generator "^6.24.1"
-    babel-plugin-syntax-async-functions "^6.8.0"
-    babel-runtime "^6.22.0"
+    define-properties "^1.1.2"
+    es-abstract "^1.7.0"
 
-babel-plugin-transform-class-properties@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac"
+array-union@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+  integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=
   dependencies:
-    babel-helper-function-name "^6.24.1"
-    babel-plugin-syntax-class-properties "^6.8.0"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
+    array-uniq "^1.0.1"
 
-babel-plugin-transform-decorators-legacy@^1.3.4:
-  version "1.3.4"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz#741b58f6c5bce9e6027e0882d9c994f04f366925"
-  dependencies:
-    babel-plugin-syntax-decorators "^6.1.18"
-    babel-runtime "^6.2.0"
-    babel-template "^6.3.0"
+array-uniq@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+  integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
 
-babel-plugin-transform-es2015-arrow-functions@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"
-  dependencies:
-    babel-runtime "^6.22.0"
+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=
 
-babel-plugin-transform-es2015-block-scoped-functions@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141"
-  dependencies:
-    babel-runtime "^6.22.0"
+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=
 
-babel-plugin-transform-es2015-block-scoping@^6.23.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f"
+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"
+  integrity sha512-rVqIs330nLJvfC7JqYvEWwqVr5QjYF1ib02i3YJtR/fICO6527Tjpc/e4Mvmxh3GIePPreRXMdaGyC99YphWEw==
   dependencies:
-    babel-runtime "^6.26.0"
-    babel-template "^6.26.0"
-    babel-traverse "^6.26.0"
-    babel-types "^6.26.0"
-    lodash "^4.17.4"
+    define-properties "^1.1.2"
+    es-abstract "^1.10.0"
+    function-bind "^1.1.1"
 
-babel-plugin-transform-es2015-classes@^6.23.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db"
-  dependencies:
-    babel-helper-define-map "^6.24.1"
-    babel-helper-function-name "^6.24.1"
-    babel-helper-optimise-call-expression "^6.24.1"
-    babel-helper-replace-supers "^6.24.1"
-    babel-messages "^6.23.0"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
-    babel-traverse "^6.24.1"
-    babel-types "^6.24.1"
+arrify@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+  integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
 
-babel-plugin-transform-es2015-computed-properties@^6.22.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3"
-  dependencies:
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
+asap@~2.0.3:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+  integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
 
-babel-plugin-transform-es2015-destructuring@^6.23.0:
-  version "6.23.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d"
+asn1.js@^4.0.0:
+  version "4.10.1"
+  resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
+  integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==
   dependencies:
-    babel-runtime "^6.22.0"
+    bn.js "^4.0.0"
+    inherits "^2.0.1"
+    minimalistic-assert "^1.0.0"
 
-babel-plugin-transform-es2015-duplicate-keys@^6.22.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e"
+asn1@~0.2.3:
+  version "0.2.4"
+  resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
+  integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
   dependencies:
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+    safer-buffer "~2.1.0"
 
-babel-plugin-transform-es2015-for-of@^6.23.0:
-  version "6.23.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691"
-  dependencies:
-    babel-runtime "^6.22.0"
+assert-plus@1.0.0, assert-plus@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+  integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
 
-babel-plugin-transform-es2015-function-name@^6.22.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b"
+assert@^1.1.1:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91"
+  integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=
   dependencies:
-    babel-helper-function-name "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+    util "0.10.3"
 
-babel-plugin-transform-es2015-literals@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e"
-  dependencies:
-    babel-runtime "^6.22.0"
+assign-symbols@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
+  integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
 
-babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154"
-  dependencies:
-    babel-plugin-transform-es2015-modules-commonjs "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
+ast-types-flow@0.0.7, ast-types-flow@^0.0.7:
+  version "0.0.7"
+  resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
+  integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
 
-babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a"
-  dependencies:
-    babel-plugin-transform-strict-mode "^6.24.1"
-    babel-runtime "^6.26.0"
-    babel-template "^6.26.0"
-    babel-types "^6.26.0"
+astral-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
+  integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
 
-babel-plugin-transform-es2015-modules-systemjs@^6.23.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23"
-  dependencies:
-    babel-helper-hoist-variables "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
+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=
 
-babel-plugin-transform-es2015-modules-umd@^6.23.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468"
-  dependencies:
-    babel-plugin-transform-es2015-modules-amd "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
+async-limiter@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
+  integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==
 
-babel-plugin-transform-es2015-object-super@^6.22.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d"
+async@^1.5.2:
+  version "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:
+  version "2.6.1"
+  resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
+  integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==
   dependencies:
-    babel-helper-replace-supers "^6.24.1"
-    babel-runtime "^6.22.0"
+    lodash "^4.17.10"
 
-babel-plugin-transform-es2015-parameters@^6.23.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b"
+asynckit@^0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+  integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
+
+atob@^2.1.1:
+  version "2.1.2"
+  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==
   dependencies:
-    babel-helper-call-delegate "^6.24.1"
-    babel-helper-get-function-arity "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
-    babel-traverse "^6.24.1"
-    babel-types "^6.24.1"
+    browserslist "^4.3.6"
+    caniuse-lite "^1.0.30000921"
+    normalize-range "^0.1.2"
+    num2fraction "^1.2.2"
+    postcss "^7.0.6"
+    postcss-value-parser "^3.3.1"
+
+aws-sign2@~0.7.0:
+  version "0.7.0"
+  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+  integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
 
-babel-plugin-transform-es2015-shorthand-properties@^6.22.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0"
-  dependencies:
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+aws4@^1.8.0:
+  version "1.8.0"
+  resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
+  integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
 
-babel-plugin-transform-es2015-spread@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1"
+axios@^0.18.0:
+  version "0.18.0"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
+  integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=
   dependencies:
-    babel-runtime "^6.22.0"
+    follow-redirects "^1.3.0"
+    is-buffer "^1.1.5"
 
-babel-plugin-transform-es2015-sticky-regex@^6.22.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc"
+axobject-query@^2.0.1:
+  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:
-    babel-helper-regex "^6.24.1"
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+    ast-types-flow "0.0.7"
 
-babel-plugin-transform-es2015-template-literals@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d"
+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:
-    babel-runtime "^6.22.0"
+    chalk "^1.1.3"
+    esutils "^2.0.2"
+    js-tokens "^3.0.2"
 
-babel-plugin-transform-es2015-typeof-symbol@^6.23.0:
-  version "6.23.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372"
+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-runtime "^6.22.0"
+    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"
+  integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@babel/parser" "^7.0.0"
+    "@babel/traverse" "^7.0.0"
+    "@babel/types" "^7.0.0"
+    eslint-scope "3.7.1"
+    eslint-visitor-keys "^1.0.0"
 
-babel-plugin-transform-es2015-unicode-regex@^6.22.0:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9"
+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-helper-regex "^6.24.1"
-    babel-runtime "^6.22.0"
-    regexpu-core "^2.0.0"
+    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-plugin-transform-exponentiation-operator@^6.22.0:
+babel-helpers@^6.24.1:
   version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e"
-  dependencies:
-    babel-helper-builder-binary-assignment-operator-visitor "^6.24.1"
-    babel-plugin-syntax-exponentiation-operator "^6.8.0"
-    babel-runtime "^6.22.0"
-
-babel-plugin-transform-flow-strip-types@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
+  resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
+  integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=
   dependencies:
-    babel-plugin-syntax-flow "^6.18.0"
     babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
 
-babel-plugin-transform-object-rest-spread@^6.23.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06"
+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==
   dependencies:
-    babel-plugin-syntax-object-rest-spread "^6.8.0"
-    babel-runtime "^6.26.0"
+    babel-plugin-istanbul "^4.1.6"
+    babel-preset-jest "^23.2.0"
 
-babel-plugin-transform-react-display-name@^6.23.0:
-  version "6.25.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1"
+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:
-    babel-runtime "^6.22.0"
+    find-cache-dir "^1.0.0"
+    loader-utils "^1.0.2"
+    mkdirp "^0.5.1"
+    util.promisify "^1.0.0"
 
-babel-plugin-transform-react-inline-elements@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-inline-elements/-/babel-plugin-transform-react-inline-elements-6.22.0.tgz#6687211a32b49a52f22c573a2b5504a25ef17c53"
+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=
   dependencies:
     babel-runtime "^6.22.0"
 
-babel-plugin-transform-react-jsx-self@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e"
+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==
   dependencies:
-    babel-plugin-syntax-jsx "^6.8.0"
-    babel-runtime "^6.22.0"
+    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"
 
-babel-plugin-transform-react-jsx-source@^6.22.0:
-  version "6.22.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6"
-  dependencies:
-    babel-plugin-syntax-jsx "^6.8.0"
-    babel-runtime "^6.22.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-transform-react-jsx@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3"
+babel-plugin-lodash@^3.3.4:
+  version "3.3.4"
+  resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz#4f6844358a1340baed182adbeffa8df9967bc196"
+  integrity sha512-yDZLjK7TCkWl1gpBeBGmuaDIFhZKmkoL+Cu2MUUjv5VxUZx/z7tBGBCBcQs5RI1Bkz5LLmNdjx7paOyQtMovyg==
   dependencies:
-    babel-helper-builder-react-jsx "^6.24.1"
-    babel-plugin-syntax-jsx "^6.8.0"
-    babel-runtime "^6.22.0"
-
-babel-plugin-transform-react-remove-prop-types@^0.4.10:
-  version "0.4.10"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.10.tgz#3c7f3a03ad8aa6bb8c00e93fd13a433910444545"
+    "@babel/helper-module-imports" "^7.0.0-beta.49"
+    "@babel/types" "^7.0.0-beta.49"
+    glob "^7.1.1"
+    lodash "^4.17.10"
+    require-package-name "^2.0.1"
 
-babel-plugin-transform-regenerator@^6.22.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f"
+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"
+  integrity sha512-M8cE1Rx0zgfKYBWAS+T6ZVCLGuTKdBI5Rn3fu9q6iVdH0UjaXdmF501/VEYn7kLHCgguhGNk5JBzOn64e2xDEA==
   dependencies:
-    regenerator-transform "^0.10.0"
+    cosmiconfig "^5.0.5"
+    resolve "^1.8.1"
 
-babel-plugin-transform-runtime@^6.23.0:
-  version "6.23.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee"
+babel-plugin-preval@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-preval/-/babel-plugin-preval-3.0.1.tgz#a26f9690114a864a54a5cbdf865496ebf541a9c3"
+  integrity sha512-s8hmTlRSmzcL7cHSIi0s6WxmpOAxfIlWqSVQwBIt7V5bNBaac+8JMZ6kJXLOazMJ8gCIcb5AJgQUgPHvbSYUzw==
   dependencies:
-    babel-runtime "^6.22.0"
+    babel-plugin-macros "^2.2.2"
+    require-from-string "^2.0.2"
 
-babel-plugin-transform-strict-mode@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758"
+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==
   dependencies:
-    babel-runtime "^6.22.0"
-    babel-types "^6.24.1"
+    "@babel/runtime" "^7.0.0"
+    intl-messageformat-parser "^1.2.0"
+    mkdirp "^0.5.1"
 
-babel-preset-env@^1.6.1:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48"
-  dependencies:
-    babel-plugin-check-es2015-constants "^6.22.0"
-    babel-plugin-syntax-trailing-function-commas "^6.22.0"
-    babel-plugin-transform-async-to-generator "^6.22.0"
-    babel-plugin-transform-es2015-arrow-functions "^6.22.0"
-    babel-plugin-transform-es2015-block-scoped-functions "^6.22.0"
-    babel-plugin-transform-es2015-block-scoping "^6.23.0"
-    babel-plugin-transform-es2015-classes "^6.23.0"
-    babel-plugin-transform-es2015-computed-properties "^6.22.0"
-    babel-plugin-transform-es2015-destructuring "^6.23.0"
-    babel-plugin-transform-es2015-duplicate-keys "^6.22.0"
-    babel-plugin-transform-es2015-for-of "^6.23.0"
-    babel-plugin-transform-es2015-function-name "^6.22.0"
-    babel-plugin-transform-es2015-literals "^6.22.0"
-    babel-plugin-transform-es2015-modules-amd "^6.22.0"
-    babel-plugin-transform-es2015-modules-commonjs "^6.23.0"
-    babel-plugin-transform-es2015-modules-systemjs "^6.23.0"
-    babel-plugin-transform-es2015-modules-umd "^6.23.0"
-    babel-plugin-transform-es2015-object-super "^6.22.0"
-    babel-plugin-transform-es2015-parameters "^6.23.0"
-    babel-plugin-transform-es2015-shorthand-properties "^6.22.0"
-    babel-plugin-transform-es2015-spread "^6.22.0"
-    babel-plugin-transform-es2015-sticky-regex "^6.22.0"
-    babel-plugin-transform-es2015-template-literals "^6.22.0"
-    babel-plugin-transform-es2015-typeof-symbol "^6.23.0"
-    babel-plugin-transform-es2015-unicode-regex "^6.22.0"
-    babel-plugin-transform-exponentiation-operator "^6.22.0"
-    babel-plugin-transform-regenerator "^6.22.0"
-    browserslist "^2.1.2"
-    invariant "^2.2.2"
-    semver "^5.3.0"
+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-preset-flow@^6.23.0:
-  version "6.23.0"
-  resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d"
-  dependencies:
-    babel-plugin-transform-flow-strip-types "^6.22.0"
+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-preset-jest@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz#ff9d2bce08abd98e8a36d9a8a5189b9173b85638"
+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=
   dependencies:
-    babel-plugin-jest-hoist "^21.2.0"
+    babel-plugin-jest-hoist "^23.2.0"
     babel-plugin-syntax-object-rest-spread "^6.13.0"
 
-babel-preset-react@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380"
-  dependencies:
-    babel-plugin-syntax-jsx "^6.3.13"
-    babel-plugin-transform-react-display-name "^6.23.0"
-    babel-plugin-transform-react-jsx "^6.24.1"
-    babel-plugin-transform-react-jsx-self "^6.22.0"
-    babel-plugin-transform-react-jsx-source "^6.22.0"
-    babel-preset-flow "^6.23.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"
@@ -1124,16 +1489,18 @@ babel-register@^6.26.0:
     mkdirp "^0.5.1"
     source-map-support "^0.4.15"
 
-babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0:
+babel-runtime@^6.22.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=
   dependencies:
     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, babel-template@^6.3.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"
@@ -1141,9 +1508,10 @@ babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0, babel-te
     babylon "^6.18.0"
     lodash "^4.17.4"
 
-babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
+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"
@@ -1155,103 +1523,118 @@ babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
     invariant "^2.2.2"
     lodash "^4.17.4"
 
-babel-types@7.0.0-beta.3:
-  version "7.0.0-beta.3"
-  resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.3.tgz#cd927ca70e0ae8ab05f4aab83778cfb3e6eb20b4"
-  dependencies:
-    esutils "^2.0.2"
-    lodash "^4.2.0"
-    to-fast-properties "^2.0.0"
-
-babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0:
+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@7.0.0-beta.36:
-  version "7.0.0-beta.36"
-  resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.36.tgz#3a3683ba6a9a1e02b0aa507c8e63435e39305b9e"
-
-babylon@7.0.0-beta.44:
-  version "7.0.0-beta.44"
-  resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d"
-
 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"
+  integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=
   dependencies:
     precond "0.2"
 
-balanced-match@0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.1.0.tgz#b504bd05869b39259dd0c5efc35d843176dccc4a"
-
-balanced-match@^0.4.2:
-  version "0.4.2"
-  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
-
 balanced-match@^1.0.0:
   version "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:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886"
+base64-js@^1.0.2, base64-js@^1.3.0:
+  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==
+
+base@^0.11.1:
+  version "0.11.2"
+  resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
+  integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==
+  dependencies:
+    cache-base "^1.0.1"
+    class-utils "^0.3.5"
+    component-emitter "^1.2.1"
+    define-property "^1.0.0"
+    isobject "^3.0.1"
+    mixin-deep "^1.2.0"
+    pascalcase "^0.1.1"
 
 batch@0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
+  integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
 
 bcrypt-pbkdf@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
+  integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
   dependencies:
     tweetnacl "^0.14.3"
 
+bfj@^6.1.1:
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.1.tgz#05a3b7784fbd72cfa3c22e56002ef99336516c48"
+  integrity sha512-+GUNvzHR4nRyGybQc2WpNJL4MJazMuvf92ueIyA0bIkPRwhhQu3IfZQ2PSoVPpCBJfmoSdOxu5rnotfFLlvYRQ==
+  dependencies:
+    bluebird "^3.5.1"
+    check-types "^7.3.0"
+    hoopy "^0.1.2"
+    tryer "^1.0.0"
+
 big.js@^3.1.3:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
+  integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==
+
+big.js@^5.2.2:
+  version "5.2.2"
+  resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
+  integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
 
 binary-extensions@^1.0.0:
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
+  version "1.12.0"
+  resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14"
+  integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==
 
-block-stream@*:
-  version "0.0.9"
-  resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
-  dependencies:
-    inherits "~2.0.0"
+bluebird@^3.5.1, bluebird@^3.5.3:
+  version "3.5.3"
+  resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7"
+  integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==
 
 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.2:
-  version "1.18.2"
-  resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454"
+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=
   dependencies:
     bytes "3.0.0"
     content-type "~1.0.4"
     debug "2.6.9"
-    depd "~1.1.1"
-    http-errors "~1.6.2"
-    iconv-lite "0.4.19"
+    depd "~1.1.2"
+    http-errors "~1.6.3"
+    iconv-lite "0.4.23"
     on-finished "~2.3.0"
-    qs "6.5.1"
-    raw-body "2.3.2"
-    type-is "~1.6.15"
+    qs "6.5.2"
+    raw-body "2.3.3"
+    type-is "~1.6.16"
 
 bonjour@^3.5.0:
   version "3.5.0"
   resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5"
+  integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU=
   dependencies:
     array-flatten "^2.1.0"
     deep-equal "^1.0.1"
@@ -1260,31 +1643,15 @@ bonjour@^3.5.0:
     multicast-dns "^6.0.1"
     multicast-dns-service-types "^1.1.0"
 
-boolbase@~1.0.0:
+boolbase@^1.0.0, boolbase@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
-
-boom@2.x.x:
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
-  dependencies:
-    hoek "2.x.x"
-
-boom@4.x.x:
-  version "4.3.1"
-  resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
-  dependencies:
-    hoek "4.x.x"
-
-boom@5.x.x:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
-  dependencies:
-    hoek "4.x.x"
+  integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
 
 brace-expansion@^1.1.7:
-  version "1.1.8"
-  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
+  version "1.1.11"
+  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+  integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
   dependencies:
     balanced-match "^1.0.0"
     concat-map "0.0.1"
@@ -1292,24 +1659,56 @@ brace-expansion@^1.1.7:
 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:
+  version "2.3.2"
+  resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
+  integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==
+  dependencies:
+    arr-flatten "^1.1.0"
+    array-unique "^0.3.2"
+    extend-shallow "^2.0.1"
+    fill-range "^4.0.0"
+    isobject "^3.0.1"
+    repeat-element "^1.1.2"
+    snapdragon "^0.8.1"
+    snapdragon-node "^2.0.1"
+    split-string "^3.0.2"
+    to-regex "^3.0.1"
+
+bricks.js@^1.7.0:
+  version "1.8.0"
+  resolved "https://registry.yarnpkg.com/bricks.js/-/bricks.js-1.8.0.tgz#8fdeb3c0226af251f4d5727a7df7f9ac0092b4b2"
+  integrity sha1-j96zwCJq8lH01XJ6fff5rACStLI=
+  dependencies:
+    knot.js "^1.1.5"
+
 brorand@^1.0.1:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
+  integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
+
+browser-process-hrtime@^0.1.2:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4"
+  integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==
 
-browser-resolve@^1.11.2:
-  version "1.11.2"
-  resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce"
+browser-resolve@^1.11.3:
+  version "1.11.3"
+  resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6"
+  integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==
   dependencies:
     resolve "1.1.7"
 
 browserify-aes@^1.0.0, browserify-aes@^1.0.4:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f"
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
+  integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
   dependencies:
     buffer-xor "^1.0.3"
     cipher-base "^1.0.0"
@@ -1319,24 +1718,28 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4:
     safe-buffer "^5.0.1"
 
 browserify-cipher@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a"
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
+  integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
   dependencies:
     browserify-aes "^1.0.4"
     browserify-des "^1.0.0"
     evp_bytestokey "^1.0.0"
 
 browserify-des@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd"
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
+  integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
   dependencies:
     cipher-base "^1.0.1"
     des.js "^1.0.0"
     inherits "^2.0.1"
+    safe-buffer "^5.1.2"
 
 browserify-rsa@^4.0.0:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524"
+  integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=
   dependencies:
     bn.js "^4.1.0"
     randombytes "^2.0.1"
@@ -1344,6 +1747,7 @@ browserify-rsa@^4.0.0:
 browserify-sign@^4.0.0:
   version "4.0.4"
   resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298"
+  integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=
   dependencies:
     bn.js "^4.1.1"
     browserify-rsa "^4.0.0"
@@ -1356,141 +1760,177 @@ browserify-sign@^4.0.0:
 browserify-zlib@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
+  integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
   dependencies:
     pako "~1.0.5"
 
-browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
-  version "1.7.7"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9"
-  dependencies:
-    caniuse-db "^1.0.30000639"
-    electron-to-chromium "^1.2.7"
-
-browserslist@^2.1.2, browserslist@^2.5.1:
-  version "2.9.1"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.9.1.tgz#b72d3982ab01b5cd24da62ff6d45573886aff275"
+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==
   dependencies:
-    caniuse-lite "^1.0.30000770"
-    electron-to-chromium "^1.3.27"
+    caniuse-lite "^1.0.30000925"
+    electron-to-chromium "^1.3.96"
+    node-releases "^1.1.3"
 
 bser@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719"
+  integrity sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=
   dependencies:
     node-int64 "^0.4.0"
 
+buffer-from@^1.0.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
+  integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
+
 buffer-indexof@^1.0.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
+  integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==
 
 buffer-writer@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-1.0.1.tgz#22a936901e3029afcd7547eb4487ceb697a3bf08"
+  integrity sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg=
 
 buffer-xor@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
+  integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
 
 buffer@^4.3.0:
   version "4.9.1"
   resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
+  integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=
   dependencies:
     base64-js "^1.0.2"
     ieee754 "^1.1.4"
     isarray "^1.0.0"
 
-builtin-modules@^1.0.0, builtin-modules@^1.1.1:
+builtin-modules@^1.0.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
+  integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
 
 builtin-status-codes@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
+  integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
 
 bytes@3.0.0:
   version "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:
+  version "11.3.2"
+  resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa"
+  integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==
+  dependencies:
+    bluebird "^3.5.3"
+    chownr "^1.1.1"
+    figgy-pudding "^3.5.1"
+    glob "^7.1.3"
+    graceful-fs "^4.1.15"
+    lru-cache "^5.1.1"
+    mississippi "^3.0.0"
+    mkdirp "^0.5.1"
+    move-concurrently "^1.0.1"
+    promise-inflight "^1.0.1"
+    rimraf "^2.6.2"
+    ssri "^6.0.1"
+    unique-filename "^1.1.1"
+    y18n "^4.0.0"
+
+cache-base@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
+  integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==
+  dependencies:
+    collection-visit "^1.0.0"
+    component-emitter "^1.2.1"
+    get-value "^2.0.6"
+    has-value "^1.0.0"
+    isobject "^3.0.1"
+    set-value "^2.0.0"
+    to-object-path "^0.3.0"
+    union-value "^1.0.0"
+    unset-value "^1.0.0"
+
+caller-callsite@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
+  integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=
+  dependencies:
+    callsites "^2.0.0"
 
 caller-path@^0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
+  integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=
   dependencies:
     callsites "^0.2.0"
 
+caller-path@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4"
+  integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=
+  dependencies:
+    caller-callsite "^2.0.0"
+
 callsites@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
+  integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=
 
 callsites@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
+  integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
 
-camelcase-css@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-1.0.1.tgz#157c4238265f5cf94a1dffde86446552cbf3f705"
-
-camelcase-keys@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
-  dependencies:
-    camelcase "^2.0.0"
-    map-obj "^1.0.0"
-
-camelcase@^1.0.2, camelcase@^1.2.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
-
-camelcase@^2.0.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
-
-camelcase@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
-
-camelcase@^4.0.0, camelcase@^4.1.0:
+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=
 
-caniuse-api@^1.5.2:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c"
+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==
+
+caniuse-api@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
+  integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==
   dependencies:
-    browserslist "^1.3.6"
-    caniuse-db "^1.0.30000529"
+    browserslist "^4.0.0"
+    caniuse-lite "^1.0.0"
     lodash.memoize "^4.1.2"
     lodash.uniq "^4.5.0"
 
-caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
-  version "1.0.30000777"
-  resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000777.tgz#2e19adba63bdd7c501df637a862adead7f4bc054"
-
-caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000770:
-  version "1.0.30000777"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000777.tgz#31c18a4a8cd49782ebb305c8e8a93e6b3b3e4f13"
+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==
 
-caseless@~0.11.0:
-  version "0.11.0"
-  resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
+capture-exit@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f"
+  integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=
+  dependencies:
+    rsvp "^3.3.3"
 
 caseless@~0.12.0:
   version "0.12.0"
   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+  integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
 
-center-align@^0.1.1:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
-  dependencies:
-    align-text "^0.1.3"
-    lazy-cache "^1.0.3"
-
-chain-function@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
-
-chalk@^1.1.1, chalk@^1.1.3:
+chalk@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+  integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
   dependencies:
     ansi-styles "^2.2.1"
     escape-string-regexp "^1.0.2"
@@ -1498,21 +1938,29 @@ chalk@^1.1.1, chalk@^1.1.3:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
-chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
+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==
   dependencies:
-    ansi-styles "^3.1.0"
+    ansi-styles "^3.2.1"
     escape-string-regexp "^1.0.5"
-    supports-color "^4.0.0"
+    supports-color "^5.3.0"
 
-chardet@^0.4.0:
-  version "0.4.2"
-  resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
+chardet@^0.7.0:
+  version "0.7.0"
+  resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
+  integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
+
+check-types@^7.3.0:
+  version "7.4.0"
+  resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4"
+  integrity sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg==
 
 cheerio@^1.0.0-rc.2:
   version "1.0.0-rc.2"
   resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db"
+  integrity sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=
   dependencies:
     css-select "~1.2.0"
     dom-serializer "~0.1.0"
@@ -1521,28 +1969,47 @@ cheerio@^1.0.0-rc.2:
     lodash "^4.15.0"
     parse5 "^3.0.1"
 
-chokidar@^1.6.0, chokidar@^1.7.0:
-  version "1.7.0"
-  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
+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==
   dependencies:
-    anymatch "^1.3.0"
+    anymatch "^2.0.0"
     async-each "^1.0.0"
-    glob-parent "^2.0.0"
+    braces "^2.3.0"
+    glob-parent "^3.1.0"
     inherits "^2.0.1"
     is-binary-path "^1.0.0"
-    is-glob "^2.0.0"
+    is-glob "^4.0.0"
+    lodash.debounce "^4.0.8"
+    normalize-path "^2.1.1"
     path-is-absolute "^1.0.0"
     readdirp "^2.0.0"
+    upath "^1.0.5"
   optionalDependencies:
-    fsevents "^1.0.0"
+    fsevents "^1.2.2"
 
-ci-info@^1.0.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4"
+chownr@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494"
+  integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==
+
+chrome-trace-event@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48"
+  integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==
+  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==
 
 cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
+  integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
   dependencies:
     inherits "^2.0.1"
     safe-buffer "^5.0.1"
@@ -1550,161 +2017,198 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
 circular-json@^0.3.1:
   version "0.3.3"
   resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
+  integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
 
-clap@^1.0.9:
-  version "1.2.3"
-  resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51"
+class-utils@^0.3.5:
+  version "0.3.6"
+  resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
+  integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==
   dependencies:
-    chalk "^1.1.3"
+    arr-union "^3.1.0"
+    define-property "^0.2.5"
+    isobject "^3.0.0"
+    static-extend "^0.1.1"
 
 classnames@^2.2.5:
-  version "2.2.5"
-  resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
+  version "2.2.6"
+  resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
+  integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
 
 cli-cursor@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
+  integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=
   dependencies:
     restore-cursor "^2.0.0"
 
 cli-width@^2.0.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
-
-cliui@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
-  dependencies:
-    center-align "^0.1.1"
-    right-align "^0.1.1"
-    wordwrap "0.0.2"
+  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"
 
-clone-deep@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.3.0.tgz#348c61ae9cdbe0edfe053d91ff4cc521d790ede8"
+cliui@^4.0.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
+  integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
   dependencies:
-    for-own "^1.0.0"
-    is-plain-object "^2.0.1"
-    kind-of "^3.2.2"
-    shallow-clone "^0.1.2"
+    string-width "^2.1.1"
+    strip-ansi "^4.0.0"
+    wrap-ansi "^2.0.0"
 
-clone@^1.0.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f"
+clone-deep@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-2.0.2.tgz#00db3a1e173656730d1188c3d6aced6d7ea97713"
+  integrity sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==
+  dependencies:
+    for-own "^1.0.0"
+    is-plain-object "^2.0.4"
+    kind-of "^6.0.0"
+    shallow-clone "^1.0.0"
 
 co@^4.6.0:
   version "4.6.0"
   resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+  integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
 
-coa@~1.0.1:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd"
+coa@~2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3"
+  integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==
   dependencies:
+    "@types/q" "^1.5.1"
+    chalk "^2.4.1"
     q "^1.1.2"
 
 code-point-at@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+  integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
 
-color-convert@^1.3.0, color-convert@^1.9.0:
-  version "1.9.1"
-  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
+collection-visit@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
+  integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=
+  dependencies:
+    map-visit "^1.0.0"
+    object-visit "^1.0.0"
+
+color-convert@^1.9.0, color-convert@^1.9.1:
+  version "1.9.3"
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+  integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
   dependencies:
-    color-name "^1.1.1"
+    color-name "1.1.3"
 
-color-name@^1.0.0, color-name@^1.1.1:
+color-name@1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+  integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
 
-color-string@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991"
-  dependencies:
-    color-name "^1.0.0"
+color-name@^1.0.0:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+  integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
 
-color@^0.11.0:
-  version "0.11.4"
-  resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764"
+color-string@^1.5.2:
+  version "1.5.3"
+  resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
+  integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==
   dependencies:
-    clone "^1.0.2"
-    color-convert "^1.3.0"
-    color-string "^0.3.0"
+    color-name "^1.0.0"
+    simple-swizzle "^0.2.2"
 
-colormin@^1.0.5:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133"
+color@^3.0.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/color/-/color-3.1.0.tgz#d8e9fb096732875774c84bf922815df0308d0ffc"
+  integrity sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg==
   dependencies:
-    color "^0.11.0"
-    css-color-names "0.0.4"
-    has "^1.0.1"
-
-colors@0.5.x:
-  version "0.5.1"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
+    color-convert "^1.9.1"
+    color-string "^1.5.2"
 
 colors@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
+  integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM=
 
-combined-stream@^1.0.5, combined-stream@~1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+combined-stream@^1.0.6, combined-stream@~1.0.6:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
+  integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
   dependencies:
     delayed-stream "~1.0.0"
 
-commander@^2.8.1, commander@^2.9.0:
-  version "2.12.2"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
+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.17.1:
+  version "2.17.1"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
+  integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
 
 commondir@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+  integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
 
-complex.js@2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.4.tgz#d8e7cfb9652d1e853e723386421c1a0ca7a48373"
+component-emitter@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
+  integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=
 
-compressible@~2.0.11:
-  version "2.0.12"
-  resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66"
+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==
   dependencies:
-    mime-db ">= 1.30.0 < 2"
+    mime-db ">= 1.36.0 < 2"
 
-compression-webpack-plugin@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-1.0.1.tgz#7f0a2af9f642b4f87b5989516a3b9e9b41bb4b3f"
-  dependencies:
-    async "2.4.1"
+compression-webpack-plugin@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-2.0.0.tgz#46476350c1eb27f783dccc79ac2f709baa2cffbc"
+  integrity sha512-bDgd7oTUZC8EkRx8j0sjyCfeiO+e5sFcfgaFcjVhfQf5lLya7oY2BczxcJ7IUuVjz5m6fy8IECFmVFew3xLk8Q==
+  dependencies:
+    cacache "^11.2.0"
+    find-cache-dir "^2.0.0"
+    neo-async "^2.5.0"
+    schema-utils "^1.0.0"
+    serialize-javascript "^1.4.0"
     webpack-sources "^1.0.1"
 
 compression@^1.5.2:
-  version "1.7.1"
-  resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.1.tgz#eff2603efc2e22cf86f35d2eb93589f9875373db"
+  version "1.7.3"
+  resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db"
+  integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==
   dependencies:
-    accepts "~1.3.4"
+    accepts "~1.3.5"
     bytes "3.0.0"
-    compressible "~2.0.11"
+    compressible "~2.0.14"
     debug "2.6.9"
     on-headers "~1.0.1"
-    safe-buffer "5.1.1"
+    safe-buffer "5.1.2"
     vary "~1.1.2"
 
 concat-map@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+  integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
 
-concat-stream@^1.6.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
+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==
   dependencies:
+    buffer-from "^1.0.0"
     inherits "^2.0.3"
     readable-stream "^2.2.2"
     typedarray "^0.0.6"
@@ -1712,105 +2216,142 @@ concat-stream@^1.6.0:
 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=
 
 console-browserify@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
+  integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=
   dependencies:
     date-now "^0.1.4"
 
 console-control-strings@^1.0.0, console-control-strings@~1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
+  integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
 
 constants-browserify@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
+  integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
 
 contains-path@^0.1.0:
   version "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"
-
-content-type-parser@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7"
+  integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ=
 
 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@^0.3.3:
-  version "0.3.5"
-  resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190"
-
-convert-source-map@^1.1.1, convert-source-map@^1.4.0, convert-source-map@^1.5.0:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
+convert-source-map@^1.1.0, convert-source-map@^1.4.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==
+  dependencies:
+    safe-buffer "~5.1.1"
 
 cookie-signature@1.0.6:
   version "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=
+
+copy-concurrently@^1.0.0:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
+  integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==
+  dependencies:
+    aproba "^1.1.1"
+    fs-write-stream-atomic "^1.0.8"
+    iferr "^0.1.5"
+    mkdirp "^0.5.1"
+    rimraf "^2.5.4"
+    run-queue "^1.0.0"
+
+copy-descriptor@^0.1.0:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
+  integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
 
 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:
-  version "2.5.1"
-  resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
+  version "2.6.1"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042"
+  integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==
 
 core-util-is@1.0.2, core-util-is@~1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+  integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
 
-cosmiconfig@3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397"
+cosmiconfig@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc"
+  integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==
   dependencies:
     is-directory "^0.3.1"
     js-yaml "^3.9.0"
-    parse-json "^3.0.0"
+    parse-json "^4.0.0"
     require-from-string "^2.0.1"
 
-cosmiconfig@^2.1.0, cosmiconfig@^2.1.1:
-  version "2.2.2"
-  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892"
+cosmiconfig@^5.0.0, cosmiconfig@^5.0.5:
+  version "5.0.7"
+  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04"
+  integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==
   dependencies:
+    import-fresh "^2.0.0"
     is-directory "^0.3.1"
-    js-yaml "^3.4.3"
-    minimist "^1.2.0"
-    object-assign "^4.1.0"
-    os-homedir "^1.0.1"
-    parse-json "^2.2.0"
-    require-from-string "^1.1.0"
+    js-yaml "^3.9.0"
+    parse-json "^4.0.0"
 
 create-ecdh@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d"
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
+  integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==
   dependencies:
     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==
+  dependencies:
+    "@emotion/cache" "10.0.0"
+    "@emotion/serialize" "^0.11.3"
+    "@emotion/sheet" "0.9.2"
+    "@emotion/utils" "0.11.1"
+
 create-hash@^1.1.0, create-hash@^1.1.2:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd"
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
+  integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
   dependencies:
     cipher-base "^1.0.1"
     inherits "^2.0.1"
-    ripemd160 "^2.0.0"
+    md5.js "^1.3.4"
+    ripemd160 "^2.0.1"
     sha.js "^2.4.0"
 
 create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
-  version "1.1.6"
-  resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06"
+  version "1.1.7"
+  resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
+  integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
   dependencies:
     cipher-base "^1.0.3"
     create-hash "^1.1.0"
@@ -1819,51 +2360,38 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
-create-react-class@^15.5.2:
-  version "15.6.2"
-  resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a"
-  dependencies:
-    fbjs "^0.8.9"
-    loose-envify "^1.3.1"
-    object-assign "^4.1.1"
-
-cross-env@^5.1.1:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.1.1.tgz#b6d8ab97f304c0f71dae7277b75fe424c08dfa74"
+cross-env@^5.1.4:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2"
+  integrity sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg==
   dependencies:
-    cross-spawn "^5.1.0"
+    cross-spawn "^6.0.5"
     is-windows "^1.0.0"
 
-cross-spawn@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
-  dependencies:
-    lru-cache "^4.0.1"
-    which "^1.2.9"
-
-cross-spawn@^5.0.1, cross-spawn@^5.1.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"
 
-cryptiles@2.x.x:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
-  dependencies:
-    boom "2.x.x"
-
-cryptiles@3.x.x:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
+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"
+  integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
   dependencies:
-    boom "5.x.x"
+    nice-try "^1.0.4"
+    path-key "^2.0.1"
+    semver "^5.5.0"
+    shebang-command "^1.2.0"
+    which "^1.2.9"
 
 crypto-browserify@^3.11.0:
   version "3.12.0"
   resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
+  integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
   dependencies:
     browserify-cipher "^1.0.0"
     browserify-sign "^4.0.0"
@@ -1877,67 +2405,86 @@ crypto-browserify@^3.11.0:
     randombytes "^2.0.0"
     randomfill "^1.0.3"
 
-css-color-function@~1.3.3:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/css-color-function/-/css-color-function-1.3.3.tgz#8ed24c2c0205073339fafa004bc8c141fccb282e"
-  dependencies:
-    balanced-match "0.1.0"
-    color "^0.11.0"
-    debug "^3.1.0"
-    rgb "~0.1.0"
-
-css-color-names@0.0.4:
+css-color-names@0.0.4, css-color-names@^0.0.4:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
+  integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=
+
+css-declaration-sorter@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22"
+  integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==
+  dependencies:
+    postcss "^7.0.1"
+    timsort "^0.3.0"
 
 css-font-size-keywords@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz#854875ace9aca6a8d2ee0d345a44aae9bb6db6cb"
+  integrity sha1-hUh1rOmspqjS7g00WkSq6btttss=
 
 css-font-stretch-keywords@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/css-font-stretch-keywords/-/css-font-stretch-keywords-1.0.1.tgz#50cee9b9ba031fb5c952d4723139f1e107b54b10"
+  integrity sha1-UM7puboDH7XJUtRyMTnx4Qe1SxA=
 
 css-font-style-keywords@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/css-font-style-keywords/-/css-font-style-keywords-1.0.1.tgz#5c3532813f63b4a1de954d13cea86ab4333409e4"
+  integrity sha1-XDUygT9jtKHelU0TzqhqtDM0CeQ=
 
 css-font-weight-keywords@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/css-font-weight-keywords/-/css-font-weight-keywords-1.0.0.tgz#9bc04671ac85bc724b574ef5d3ac96b0d604fd97"
+  integrity sha1-m8BGcayFvHJLV07106yWsNYE/Zc=
 
 css-global-keywords@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/css-global-keywords/-/css-global-keywords-1.0.1.tgz#72a9aea72796d019b1d2a3252de4e5aaa37e4a69"
+  integrity sha1-cqmupyeW0Bmx0qMlLeTlqqN+Smk=
 
 css-list-helpers@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/css-list-helpers/-/css-list-helpers-1.0.1.tgz#fff57192202db83240c41686f919e449a7024f7d"
+  integrity sha1-//VxkiAtuDJAxBaG+RnkSacCT30=
   dependencies:
     tcomb "^2.5.0"
 
-css-loader@^0.28.4:
-  version "0.28.7"
-  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.7.tgz#5f2ee989dd32edd907717f953317656160999c1b"
-  dependencies:
-    babel-code-frame "^6.11.0"
-    css-selector-tokenizer "^0.7.0"
-    cssnano ">=2.6.1 <4"
-    icss-utils "^2.1.0"
-    loader-utils "^1.0.2"
-    lodash.camelcase "^4.3.0"
-    object-assign "^4.0.1"
-    postcss "^5.0.6"
-    postcss-modules-extract-imports "^1.0.0"
-    postcss-modules-local-by-default "^1.0.1"
-    postcss-modules-scope "^1.0.0"
-    postcss-modules-values "^1.1.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"
+    postcss-modules-extract-imports "^2.0.0"
+    postcss-modules-local-by-default "^2.0.3"
+    postcss-modules-scope "^2.0.0"
+    postcss-modules-values "^2.0.0"
     postcss-value-parser "^3.3.0"
-    source-list-map "^2.0.0"
+    schema-utils "^1.0.0"
+
+css-select-base-adapter@~0.1.0:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7"
+  integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==
+
+css-select@^2.0.0:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede"
+  integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==
+  dependencies:
+    boolbase "^1.0.0"
+    css-what "^2.1.2"
+    domutils "^1.7.0"
+    nth-check "^1.0.2"
 
 css-select@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
+  integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=
   dependencies:
     boolbase "~1.0.0"
     css-what "2.1"
@@ -1945,8 +2492,9 @@ css-select@~1.2.0:
     nth-check "~1.0.1"
 
 css-selector-tokenizer@^0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86"
+  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"
@@ -1955,174 +2503,292 @@ css-selector-tokenizer@^0.7.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"
+  integrity sha1-hcbwhquk6zLFcaMIav/ENLhII+0=
 
-css-what@2.1:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
+css-tree@1.0.0-alpha.28:
+  version "1.0.0-alpha.28"
+  resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.28.tgz#8e8968190d886c9477bc8d61e96f61af3f7ffa7f"
+  integrity sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==
+  dependencies:
+    mdn-data "~1.1.0"
+    source-map "^0.5.3"
 
-css@^2.0.0:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/css/-/css-2.2.1.tgz#73a4c81de85db664d4ee674f7d47085e3b2d55dc"
+css-tree@1.0.0-alpha.29:
+  version "1.0.0-alpha.29"
+  resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39"
+  integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==
   dependencies:
-    inherits "^2.0.1"
-    source-map "^0.1.38"
-    source-map-resolve "^0.3.0"
-    urix "^0.1.0"
+    mdn-data "~1.1.0"
+    source-map "^0.5.3"
+
+css-unit-converter@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996"
+  integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=
+
+css-url-regex@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec"
+  integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=
+
+css-what@2.1, css-what@^2.1.2:
+  version "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=
 
-"cssnano@>=2.6.1 <4":
-  version "3.10.0"
-  resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38"
+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==
+  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-convert-values "^4.0.1"
+    postcss-discard-comments "^4.0.1"
+    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-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-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-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-unique-selectors "^4.0.1"
+
+cssnano-util-get-arguments@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f"
+  integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=
+
+cssnano-util-get-match@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d"
+  integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=
+
+cssnano-util-raw-cache@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282"
+  integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==
   dependencies:
-    autoprefixer "^6.3.1"
-    decamelize "^1.1.2"
-    defined "^1.0.0"
-    has "^1.0.1"
-    object-assign "^4.0.1"
-    postcss "^5.0.14"
-    postcss-calc "^5.2.0"
-    postcss-colormin "^2.1.8"
-    postcss-convert-values "^2.3.4"
-    postcss-discard-comments "^2.0.4"
-    postcss-discard-duplicates "^2.0.1"
-    postcss-discard-empty "^2.0.1"
-    postcss-discard-overridden "^0.1.1"
-    postcss-discard-unused "^2.2.1"
-    postcss-filter-plugins "^2.0.0"
-    postcss-merge-idents "^2.1.5"
-    postcss-merge-longhand "^2.0.1"
-    postcss-merge-rules "^2.0.3"
-    postcss-minify-font-values "^1.0.2"
-    postcss-minify-gradients "^1.0.1"
-    postcss-minify-params "^1.0.4"
-    postcss-minify-selectors "^2.0.4"
-    postcss-normalize-charset "^1.1.0"
-    postcss-normalize-url "^3.0.7"
-    postcss-ordered-values "^2.1.0"
-    postcss-reduce-idents "^2.2.2"
-    postcss-reduce-initial "^1.0.0"
-    postcss-reduce-transforms "^1.0.3"
-    postcss-svgo "^2.1.1"
-    postcss-unique-selectors "^2.0.2"
-    postcss-value-parser "^3.2.3"
-    postcss-zindex "^2.0.1"
-
-csso@~2.3.1:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85"
+    postcss "^7.0.0"
+
+cssnano-util-same-parent@^4.0.0:
+  version "4.0.1"
+  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==
   dependencies:
-    clap "^1.0.9"
-    source-map "^0.5.3"
+    cosmiconfig "^5.0.0"
+    cssnano-preset-default "^4.0.6"
+    is-resolvable "^1.0.0"
+    postcss "^7.0.0"
+
+csso@^3.5.0:
+  version "3.5.1"
+  resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.1.tgz#7b9eb8be61628973c1b261e169d2f024008e758b"
+  integrity sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==
+  dependencies:
+    css-tree "1.0.0-alpha.29"
 
 cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b"
+  version "0.3.4"
+  resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797"
+  integrity sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==
 
-"cssstyle@>= 0.2.37 < 0.3.0":
-  version "0.2.37"
-  resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54"
+cssstyle@^1.0.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb"
+  integrity sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==
   dependencies:
     cssom "0.3.x"
 
-currently-unhandled@^0.4.1:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
-  dependencies:
-    array-find-index "^1.0.1"
+csstype@^2.2.0, csstype@^2.5.7:
+  version "2.6.0"
+  resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.0.tgz#6cf7b2fa7fc32aab3d746802c244d4eda71371a2"
+  integrity sha512-by8hi8BlLbowQq0qtkx54d9aN73R9oUW20HISpka5kmgsR9F7nnxgfsemuR2sdCKZh+CDNf5egW9UZMm4mgJRg==
+
+cyclist@~0.2.2:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
+  integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
 
 d@1:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
+  integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=
   dependencies:
     es5-ext "^0.10.9"
 
-damerau-levenshtein@^1.0.0:
+damerau-levenshtein@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514"
+  integrity sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=
 
 dashdash@^1.12.0:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+  integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
   dependencies:
     assert-plus "^1.0.0"
 
+data-urls@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe"
+  integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==
+  dependencies:
+    abab "^2.0.0"
+    whatwg-mimetype "^2.2.0"
+    whatwg-url "^7.0.0"
+
 date-now@^0.1.4:
   version "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.2.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
+debug@2.6.9, 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==
   dependencies:
     ms "2.0.0"
 
-debug@^3.0.1, debug@^3.1.0:
+debug@=3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
+  integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
   dependencies:
     ms "2.0.0"
 
-decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2:
+debug@^3.1.0, 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:
+  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:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+  integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
 
-decimal.js@7.2.3:
-  version "7.2.3"
-  resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-7.2.3.tgz#6434c3b8a8c375780062fc633d0d2bbdb264cc78"
+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"
+  integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
 
 deep-equal@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
+  integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
+
+deep-extend@^0.5.1:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f"
+  integrity sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==
 
-deep-extend@^0.4.0, deep-extend@~0.4.0:
-  version "0.4.2"
-  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
+deep-extend@^0.6.0:
+  version "0.6.0"
+  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
+  integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
 
 deep-is@~0.1.3:
   version "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==
+  dependencies:
+    execa "^0.10.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"
 
-defaults@^1.0.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
+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"
+  integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
   dependencies:
-    clone "^1.0.2"
+    object-keys "^1.0.12"
 
-define-properties@^1.1.1, define-properties@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
+define-property@^0.2.5:
+  version "0.2.5"
+  resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
+  integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=
   dependencies:
-    foreach "^2.0.5"
-    object-keys "^1.0.8"
+    is-descriptor "^0.1.0"
 
-defined@^1.0.0:
+define-property@^1.0.0:
   version "1.0.0"
-  resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
+  resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6"
+  integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY=
+  dependencies:
+    is-descriptor "^1.0.0"
 
-del@^2.0.2:
-  version "2.2.2"
-  resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
+define-property@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d"
+  integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==
   dependencies:
-    globby "^5.0.0"
-    is-path-cwd "^1.0.0"
-    is-path-in-cwd "^1.0.0"
-    object-assign "^4.0.1"
-    pify "^2.0.0"
-    pinkie-promise "^2.0.0"
-    rimraf "^2.2.8"
+    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=
   dependencies:
     globby "^6.1.0"
     is-path-cwd "^1.0.0"
@@ -2134,18 +2800,22 @@ del@^3.0.0:
 delayed-stream@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+  integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
 
 delegates@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
+  integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
 
-depd@1.1.1, depd@~1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
+depd@~1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
+  integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
 
 des.js@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc"
+  integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=
   dependencies:
     inherits "^2.0.1"
     minimalistic-assert "^1.0.0"
@@ -2153,32 +2823,44 @@ des.js@^1.0.0:
 destroy@~1.0.4:
   version "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-libc@^1.0.2:
+detect-libc@^1.0.2, detect-libc@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
+  integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
 
-detect-node@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127"
+detect-newline@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
+  integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=
+
+detect-node@^2.0.4:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
+  integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
 
 detect-passive-events@^1.0.2:
   version "1.0.4"
   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.4.0"
-  resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
+  version "3.5.0"
+  resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
+  integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
 
 diffie-hellman@^5.0.0:
-  version "5.0.2"
-  resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e"
+  version "5.0.3"
+  resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
+  integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
   dependencies:
     bn.js "^4.1.0"
     miller-rabin "^4.0.0"
@@ -2187,14 +2869,17 @@ diffie-hellman@^5.0.0:
 discontinuous-range@1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
+  integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=
 
 dns-equal@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
+  integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=
 
-dns-packet@^1.0.1:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.2.2.tgz#a8a26bec7646438963fc86e06f8f8b16d6c8bf7a"
+dns-packet@^1.3.1:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a"
+  integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==
   dependencies:
     ip "^1.1.0"
     safe-buffer "^5.0.1"
@@ -2202,98 +2887,144 @@ dns-packet@^1.0.1:
 dns-txt@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6"
+  integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=
   dependencies:
     buffer-indexof "^1.0.0"
 
 doctrine@1.5.0:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
+  integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=
   dependencies:
     esutils "^2.0.2"
     isarray "^1.0.0"
 
-doctrine@^2.0.2, doctrine@^2.1.0:
+doctrine@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
+  integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
   dependencies:
     esutils "^2.0.2"
 
-dom-helpers@^3.2.0, dom-helpers@^3.2.1:
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
+dom-helpers@^3.2.1, dom-helpers@^3.3.1:
+  version "3.4.0"
+  resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
+  integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
+  dependencies:
+    "@babel/runtime" "^7.1.2"
 
 dom-serializer@0, dom-serializer@~0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
+  integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=
   dependencies:
     domelementtype "~1.1.1"
     entities "~1.1.1"
 
 domain-browser@^1.1.1:
-  version "1.1.7"
-  resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
+  integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
 
 domelementtype@1, domelementtype@^1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
+  integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
 
 domelementtype@~1.1.1:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+  integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=
+
+domexception@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
+  integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==
+  dependencies:
+    webidl-conversions "^4.0.2"
 
 domhandler@^2.3.0:
-  version "2.4.1"
-  resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"
+  version "2.4.2"
+  resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
+  integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
   dependencies:
     domelementtype "1"
 
 domutils@1.5.1:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
+  integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=
   dependencies:
     dom-serializer "0"
     domelementtype "1"
 
-domutils@^1.5.1:
-  version "1.6.2"
-  resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.6.2.tgz#1958cc0b4c9426e9ed367fb1c8e854891b0fa3ff"
+domutils@^1.5.1, domutils@^1.7.0:
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
+  integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
   dependencies:
     dom-serializer "0"
     domelementtype "1"
 
-dotenv@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d"
+dot-prop@^4.1.1:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
+  integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==
+  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==
 
 double-ended-queue@^2.1.0-0:
   version "2.1.0-0"
   resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
+  integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=
 
-duplexer@^0.1.1, duplexer@~0.1.1:
+duplexer@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
+  integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=
+
+duplexify@^3.4.2, duplexify@^3.6.0:
+  version "3.6.1"
+  resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125"
+  integrity sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==
+  dependencies:
+    end-of-stream "^1.0.0"
+    inherits "^2.0.1"
+    readable-stream "^2.0.0"
+    stream-shift "^1.0.0"
 
 ecc-jsbn@~0.1.1:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
+  integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
   dependencies:
     jsbn "~0.1.0"
+    safer-buffer "^2.1.0"
 
 ee-first@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
+  integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
 
-ejs@^2.3.4, ejs@^2.5.6:
-  version "2.5.7"
-  resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a"
+ejs@^2.3.4, ejs@^2.6.1:
+  version "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.2.7, electron-to-chromium@^1.3.27:
-  version "1.3.27"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d"
+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==
 
 elliptic@^6.0.0:
-  version "6.4.0"
-  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
+  version "6.4.1"
+  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a"
+  integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==
   dependencies:
     bn.js "^4.4.0"
     brorand "^1.0.1"
@@ -2307,87 +3038,115 @@ emoji-mart@Gargron/emoji-mart#build:
   version "2.6.2"
   resolved "https://codeload.github.com/Gargron/emoji-mart/tar.gz/ff00dc470b5b2d9f145a6d6e977a54de5df2b4c9"
 
-emoji-regex@^6.1.0:
+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==
 
 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=
 
-encodeurl@~1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
+encodeurl@~1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
+  integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
 
 encoding@^0.1.11:
   version "0.1.12"
   resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
+  integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
   dependencies:
     iconv-lite "~0.4.13"
 
-enhanced-resolve@^3.4.0:
-  version "3.4.1"
-  resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e"
+end-of-stream@^1.0.0, end-of-stream@^1.1.0:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
+  integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==
+  dependencies:
+    once "^1.4.0"
+
+enhanced-resolve@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f"
+  integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==
   dependencies:
     graceful-fs "^4.1.2"
     memory-fs "^0.4.0"
-    object-assign "^4.0.1"
-    tapable "^0.2.7"
+    tapable "^1.0.0"
 
 entities@^1.1.1, entities@~1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
+  integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
 
-enzyme-adapter-react-16@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.1.0.tgz#86c5db7c10f0be6ec25d54ca41b59f2abb397cf4"
+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==
   dependencies:
-    enzyme-adapter-utils "^1.1.0"
-    lodash "^4.17.4"
-    object.assign "^4.0.4"
+    enzyme-adapter-utils "^1.9.0"
+    function.prototype.name "^1.1.0"
+    object.assign "^4.1.0"
     object.values "^1.0.4"
-    prop-types "^15.5.10"
+    prop-types "^15.6.2"
+    react-is "^16.6.1"
     react-test-renderer "^16.0.0-0"
 
-enzyme-adapter-utils@^1.1.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.2.0.tgz#7f4471ee0a70b91169ec8860d2bf0a6b551664b2"
+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==
   dependencies:
-    lodash "^4.17.4"
-    object.assign "^4.0.4"
-    prop-types "^15.5.10"
+    function.prototype.name "^1.1.0"
+    object.assign "^4.1.0"
+    prop-types "^15.6.2"
+    semver "^5.6.0"
 
-enzyme@^3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.2.0.tgz#998bdcda0fc71b8764a0017f7cc692c943f54a7a"
+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==
   dependencies:
+    array.prototype.flat "^1.2.1"
     cheerio "^1.0.0-rc.2"
-    function.prototype.name "^1.0.3"
-    has "^1.0.1"
+    function.prototype.name "^1.1.0"
+    has "^1.0.3"
+    is-boolean-object "^1.0.0"
+    is-callable "^1.1.4"
+    is-number-object "^1.0.3"
+    is-string "^1.0.4"
     is-subset "^0.1.1"
-    lodash "^4.17.4"
+    lodash.escape "^4.0.1"
+    lodash.isequal "^4.5.0"
+    object-inspect "^1.6.0"
     object-is "^1.0.1"
-    object.assign "^4.0.4"
+    object.assign "^4.1.0"
     object.entries "^1.0.4"
     object.values "^1.0.4"
     raf "^3.4.0"
     rst-selector-parser "^2.2.3"
+    string.prototype.trim "^1.1.2"
 
-errno@^0.1.3, errno@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d"
+errno@^0.1.3, errno@~0.1.7:
+  version "0.1.7"
+  resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
+  integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==
   dependencies:
-    prr "~0.0.0"
+    prr "~1.0.1"
 
 error-ex@^1.2.0, error-ex@^1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
+  version "1.3.2"
+  resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
+  integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
   dependencies:
     is-arrayish "^0.2.1"
 
-es-abstract@^1.4.3, es-abstract@^1.6.1, es-abstract@^1.7.0:
-  version "1.10.0"
-  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
+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:
+  version "1.12.0"
+  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
+  integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==
   dependencies:
     es-to-primitive "^1.1.1"
     function-bind "^1.1.1"
@@ -2396,294 +3155,292 @@ es-abstract@^1.4.3, es-abstract@^1.6.1, es-abstract@^1.7.0:
     is-regex "^1.0.4"
 
 es-to-primitive@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
+  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==
   dependencies:
-    is-callable "^1.1.1"
+    is-callable "^1.1.4"
     is-date-object "^1.0.1"
-    is-symbol "^1.0.1"
+    is-symbol "^1.0.2"
 
-es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14:
-  version "0.10.37"
-  resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3"
+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"
+  integrity sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==
   dependencies:
-    es6-iterator "~2.0.1"
+    es6-iterator "~2.0.3"
     es6-symbol "~3.1.1"
+    next-tick "1"
 
-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=
   dependencies:
     d "1"
     es5-ext "^0.10.35"
     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"
-  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"
-  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:
+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=
   dependencies:
     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"
-  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"
+  integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
 
 escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+  integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
 
-escodegen@^1.6.1:
-  version "1.9.0"
-  resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852"
+escodegen@^1.9.1:
+  version "1.11.0"
+  resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589"
+  integrity sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==
   dependencies:
     esprima "^3.1.3"
     estraverse "^4.2.0"
     esutils "^2.0.2"
     optionator "^0.8.1"
   optionalDependencies:
-    source-map "~0.5.6"
-
-escope@^3.6.0:
-  version "3.6.0"
-  resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
-  dependencies:
-    es6-map "^0.1.3"
-    es6-weak-map "^2.0.1"
-    esrecurse "^4.1.0"
-    estraverse "^4.1.1"
+    source-map "~0.6.1"
 
 eslint-import-resolver-node@^0.3.1:
   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==
   dependencies:
     debug "^2.6.9"
     resolve "^1.5.0"
 
-eslint-module-utils@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449"
+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=
   dependencies:
     debug "^2.6.8"
     pkg-dir "^1.0.0"
 
-eslint-plugin-import@^2.8.0:
-  version "2.8.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894"
+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==
   dependencies:
-    builtin-modules "^1.1.1"
     contains-path "^0.1.0"
     debug "^2.6.8"
     doctrine "1.5.0"
     eslint-import-resolver-node "^0.3.1"
-    eslint-module-utils "^2.1.1"
+    eslint-module-utils "^2.2.0"
     has "^1.0.1"
-    lodash.cond "^4.3.0"
+    lodash "^4.17.4"
     minimatch "^3.0.3"
     read-pkg-up "^2.0.0"
+    resolve "^1.6.0"
 
-eslint-plugin-jsx-a11y@^6.0.3:
-  version "6.0.3"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.3.tgz#54583d1ae442483162e040e13cc31865465100e5"
+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==
   dependencies:
-    aria-query "^0.7.0"
+    aria-query "^3.0.0"
     array-includes "^3.0.3"
-    ast-types-flow "0.0.7"
-    axobject-query "^0.1.0"
-    damerau-levenshtein "^1.0.0"
-    emoji-regex "^6.1.0"
-    jsx-ast-utils "^2.0.0"
+    ast-types-flow "^0.0.7"
+    axobject-query "^2.0.1"
+    damerau-levenshtein "^1.0.4"
+    emoji-regex "^6.5.1"
+    has "^1.0.3"
+    jsx-ast-utils "^2.0.1"
 
-eslint-plugin-promise@^3.8.0:
-  version "3.8.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz#65ebf27a845e3c1e9d6f6a5622ddd3801694b621"
+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-react@^7.8.2:
-  version "7.8.2"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.8.2.tgz#e95c9c47fece55d2303d1a67c9d01b930b88a51d"
+eslint-plugin-react@~7.12.1:
+  version "7.12.1"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.1.tgz#b9c4639f72469ff317ac31e3bd630d22d0dbf8f4"
+  integrity sha512-1YyXVhp6KSB+xRC1BWzmlA4BH9Wp9jMMBE6AJizxuk+bg/KUJpQGRwsU1/q1pV8rM6oEdLCxunXn7Nfh2BOWBg==
   dependencies:
-    doctrine "^2.0.2"
-    has "^1.0.1"
+    array-includes "^3.0.3"
+    doctrine "^2.1.0"
+    has "^1.0.3"
     jsx-ast-utils "^2.0.1"
-    prop-types "^15.6.0"
+    object.fromentries "^2.0.0"
+    prop-types "^15.6.2"
+    resolve "^1.9.0"
 
-eslint-scope@^3.7.1, eslint-scope@~3.7.1:
+eslint-scope@3.7.1:
   version "3.7.1"
   resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
+  integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=
+  dependencies:
+    esrecurse "^4.1.0"
+    estraverse "^4.1.1"
+
+eslint-scope@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172"
+  integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==
   dependencies:
     esrecurse "^4.1.0"
     estraverse "^4.1.1"
 
+eslint-utils@^1.3.1:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512"
+  integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==
+
 eslint-visitor-keys@^1.0.0:
   version "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@^4.19.1:
-  version "4.19.1"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300"
+eslint@^5.11.1:
+  version "5.11.1"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.11.1.tgz#8deda83db9f354bf9d3f53f9677af7e0e13eadda"
+  integrity sha512-gOKhM8JwlFOc2acbOrkYR05NW8M6DCMSvfcJiBB5NDxRE1gv8kbvxKaC9u69e6ZGEMWXcswA/7eKR229cEIpvg==
   dependencies:
-    ajv "^5.3.0"
-    babel-code-frame "^6.22.0"
+    "@babel/code-frame" "^7.0.0"
+    ajv "^6.5.3"
     chalk "^2.1.0"
-    concat-stream "^1.6.0"
-    cross-spawn "^5.1.0"
-    debug "^3.1.0"
+    cross-spawn "^6.0.5"
+    debug "^4.0.1"
     doctrine "^2.1.0"
-    eslint-scope "^3.7.1"
+    eslint-scope "^4.0.0"
+    eslint-utils "^1.3.1"
     eslint-visitor-keys "^1.0.0"
-    espree "^3.5.4"
-    esquery "^1.0.0"
+    espree "^5.0.0"
+    esquery "^1.0.1"
     esutils "^2.0.2"
     file-entry-cache "^2.0.0"
     functional-red-black-tree "^1.0.1"
     glob "^7.1.2"
-    globals "^11.0.1"
-    ignore "^3.3.3"
+    globals "^11.7.0"
+    ignore "^4.0.6"
     imurmurhash "^0.1.4"
-    inquirer "^3.0.6"
-    is-resolvable "^1.0.0"
-    js-yaml "^3.9.1"
+    inquirer "^6.1.0"
+    js-yaml "^3.12.0"
     json-stable-stringify-without-jsonify "^1.0.1"
     levn "^0.3.0"
-    lodash "^4.17.4"
-    minimatch "^3.0.2"
+    lodash "^4.17.5"
+    minimatch "^3.0.4"
     mkdirp "^0.5.1"
     natural-compare "^1.4.0"
     optionator "^0.8.2"
     path-is-inside "^1.0.2"
     pluralize "^7.0.0"
     progress "^2.0.0"
-    regexpp "^1.0.1"
+    regexpp "^2.0.1"
     require-uncached "^1.0.3"
-    semver "^5.3.0"
+    semver "^5.5.1"
     strip-ansi "^4.0.0"
-    strip-json-comments "~2.0.1"
-    table "4.0.2"
-    text-table "~0.2.0"
+    strip-json-comments "^2.0.1"
+    table "^5.0.2"
+    text-table "^0.2.0"
 
-espree@^3.5.4:
-  version "3.5.4"
-  resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
+espree@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.0.tgz#fc7f984b62b36a0f543b13fb9cd7b9f4a7f5b65c"
+  integrity sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==
   dependencies:
-    acorn "^5.5.0"
-    acorn-jsx "^3.0.0"
-
-esprima@^2.6.0:
-  version "2.7.3"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
+    acorn "^6.0.2"
+    acorn-jsx "^5.0.0"
+    eslint-visitor-keys "^1.0.0"
 
 esprima@^3.1.3:
   version "3.1.3"
   resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
+  integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
 
 esprima@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
+  integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
 
-esquery@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa"
+esquery@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
+  integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==
   dependencies:
     estraverse "^4.0.0"
 
 esrecurse@^4.1.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163"
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
+  integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
   dependencies:
     estraverse "^4.1.0"
-    object-assign "^4.0.1"
 
 estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
   version "4.2.0"
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
+  integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=
 
-esutils@^2.0.2:
+esutils@^2.0.0, esutils@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+  integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
 
 etag@~1.8.1:
   version "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"
-  dependencies:
-    d "1"
-    es5-ext "~0.10.14"
-
-event-stream@~3.3.0:
-  version "3.3.4"
-  resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
-  dependencies:
-    duplexer "~0.1.1"
-    from "~0"
-    map-stream "~0.1.0"
-    pause-stream "0.0.11"
-    split "0.3"
-    stream-combiner "~0.0.4"
-    through "~2.3.1"
-
-eventemitter3@1.x.x:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508"
+eventemitter3@^3.0.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163"
+  integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==
 
 events@^1.0.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
+  integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=
 
-eventsource@0.1.6:
-  version "0.1.6"
-  resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232"
+eventsource@^1.0.7:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0"
+  integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==
   dependencies:
-    original ">=0.0.5"
+    original "^1.0.0"
 
 evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
+  integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
   dependencies:
     md5.js "^1.3.4"
     safe-buffer "^5.1.1"
 
 exec-sh@^0.2.0:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38"
+  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:
-    merge "^1.1.3"
+    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"
@@ -2693,140 +3450,209 @@ execa@^0.7.0:
     signal-exit "^3.0.0"
     strip-eof "^1.0.0"
 
+execa@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
+  integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
+  dependencies:
+    cross-spawn "^6.0.0"
+    get-stream "^4.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"
+
 exif-js@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/exif-js/-/exif-js-2.3.0.tgz#9d10819bf571f873813e7640241255ab9ce1a814"
+  integrity sha1-nRCBm/Vx+HOBPnZAJBJVq5zhqBQ=
+
+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"
+  integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI=
+  dependencies:
+    debug "^2.3.3"
+    define-property "^0.2.5"
+    extend-shallow "^2.0.1"
+    posix-character-classes "^0.1.0"
+    regex-not "^1.0.0"
+    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=
   dependencies:
     fill-range "^2.1.0"
 
-expect@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/expect/-/expect-21.2.1.tgz#003ac2ac7005c3c29e73b38a272d4afadd6d1d7b"
+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==
   dependencies:
     ansi-styles "^3.2.0"
-    jest-diff "^21.2.1"
-    jest-get-type "^21.2.0"
-    jest-matcher-utils "^21.2.1"
-    jest-message-util "^21.2.1"
-    jest-regex-util "^21.2.0"
-
-express@^4.15.2, express@^4.16.2:
-  version "4.16.2"
-  resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
-  dependencies:
-    accepts "~1.3.4"
+    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"
+
+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==
+  dependencies:
+    accepts "~1.3.5"
     array-flatten "1.1.1"
-    body-parser "1.18.2"
+    body-parser "1.18.3"
     content-disposition "0.5.2"
     content-type "~1.0.4"
     cookie "0.3.1"
     cookie-signature "1.0.6"
     debug "2.6.9"
-    depd "~1.1.1"
-    encodeurl "~1.0.1"
+    depd "~1.1.2"
+    encodeurl "~1.0.2"
     escape-html "~1.0.3"
     etag "~1.8.1"
-    finalhandler "1.1.0"
+    finalhandler "1.1.1"
     fresh "0.5.2"
     merge-descriptors "1.0.1"
     methods "~1.1.2"
     on-finished "~2.3.0"
     parseurl "~1.3.2"
     path-to-regexp "0.1.7"
-    proxy-addr "~2.0.2"
-    qs "6.5.1"
+    proxy-addr "~2.0.4"
+    qs "6.5.2"
     range-parser "~1.2.0"
-    safe-buffer "5.1.1"
-    send "0.16.1"
-    serve-static "1.13.1"
+    safe-buffer "5.1.2"
+    send "0.16.2"
+    serve-static "1.13.2"
     setprototypeof "1.1.0"
-    statuses "~1.3.1"
-    type-is "~1.6.15"
+    statuses "~1.4.0"
+    type-is "~1.6.16"
     utils-merge "1.0.1"
     vary "~1.1.2"
 
-extend@~3.0.0, extend@~3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+extend-shallow@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
+  integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=
+  dependencies:
+    is-extendable "^0.1.0"
 
-external-editor@^2.0.4:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48"
+extend-shallow@^3.0.0, extend-shallow@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
+  integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=
+  dependencies:
+    assign-symbols "^1.0.0"
+    is-extendable "^1.0.1"
+
+extend@~3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
+  integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
+
+external-editor@^3.0.0:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27"
+  integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==
   dependencies:
-    chardet "^0.4.0"
-    iconv-lite "^0.4.17"
+    chardet "^0.7.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"
 
-extract-text-webpack-plugin@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7"
-  dependencies:
-    async "^2.4.1"
-    loader-utils "^1.1.0"
-    schema-utils "^0.3.0"
-    webpack-sources "^1.0.1"
+extglob@^2.0.4:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
+  integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==
+  dependencies:
+    array-unique "^0.3.2"
+    define-property "^1.0.0"
+    expand-brackets "^2.1.4"
+    extend-shallow "^2.0.1"
+    fragment-cache "^0.2.1"
+    regex-not "^1.0.0"
+    snapdragon "^0.8.1"
+    to-regex "^3.0.1"
 
 extsprintf@1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+  integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
 
 extsprintf@^1.2.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
+  integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
 
-fast-deep-equal@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
+fast-deep-equal@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
+  integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
 
 fast-json-stable-stringify@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
+  integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
 
 fast-levenshtein@~2.0.4:
   version "2.0.6"
   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.1"
-  resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
+  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"
+  integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
   dependencies:
     websocket-driver ">=0.5.1"
 
-faye-websocket@~0.11.0:
+faye-websocket@~0.11.1:
   version "0.11.1"
   resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38"
+  integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=
   dependencies:
     websocket-driver ">=0.5.1"
 
 fb-watchman@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58"
+  integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=
   dependencies:
     bser "^2.0.0"
 
-fbjs@^0.8.16, fbjs@^0.8.4, fbjs@^0.8.9:
-  version "0.8.16"
-  resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
+fbjs@^0.8.4:
+  version "0.8.17"
+  resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
+  integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
   dependencies:
     core-js "^1.0.0"
     isomorphic-fetch "^2.1.1"
@@ -2834,75 +3660,117 @@ fbjs@^0.8.16, fbjs@^0.8.4, fbjs@^0.8.9:
     object-assign "^4.1.0"
     promise "^7.1.1"
     setimmediate "^1.0.5"
-    ua-parser-js "^0.7.9"
+    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@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
+  integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
   dependencies:
     escape-string-regexp "^1.0.5"
 
 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"
+  integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=
   dependencies:
     flat-cache "^1.2.1"
     object-assign "^4.0.1"
 
-file-loader@^0.11.2:
-  version "0.11.2"
-  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.2.tgz#4ff1df28af38719a6098093b88c82c71d1794a34"
+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==
   dependencies:
     loader-utils "^1.0.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.5.9:
-  version "3.5.11"
-  resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.11.tgz#1919326749433bb3cf77368bd158caabcc19e9ee"
+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.3"
-  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
+  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 "^1.1.3"
+    randomatic "^3.0.0"
     repeat-element "^1.1.2"
     repeat-string "^1.5.2"
 
-finalhandler@1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5"
+fill-range@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
+  integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=
+  dependencies:
+    extend-shallow "^2.0.1"
+    is-number "^3.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==
   dependencies:
     debug "2.6.9"
-    encodeurl "~1.0.1"
+    encodeurl "~1.0.2"
     escape-html "~1.0.3"
     on-finished "~2.3.0"
     parseurl "~1.3.2"
-    statuses "~1.3.1"
+    statuses "~1.4.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"
+  integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==
+  dependencies:
+    commondir "^1.0.1"
+    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"
@@ -2910,149 +3778,163 @@ find-up@^1.0.0:
 find-up@^2.0.0, find-up@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
+  integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
   dependencies:
     locate-path "^2.0.0"
 
+find-up@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
+  integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
+  dependencies:
+    locate-path "^3.0.0"
+
 flat-cache@^1.2.1:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
+  version "1.3.4"
+  resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f"
+  integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==
   dependencies:
     circular-json "^0.3.1"
-    del "^2.0.2"
     graceful-fs "^4.1.2"
+    rimraf "~2.6.2"
     write "^0.2.1"
 
-flatten@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
+flush-write-stream@^1.0.0:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd"
+  integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==
+  dependencies:
+    inherits "^2.0.1"
+    readable-stream "^2.0.4"
 
-follow-redirects@^1.2.3:
-  version "1.2.6"
-  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.6.tgz#4dcdc7e4ab3dd6765a97ff89c3b4c258117c79bf"
+follow-redirects@^1.0.0, follow-redirects@^1.3.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.6.0.tgz#d12452c031e8c67eb6637d861bfc7a8090167933"
+  integrity sha512-4Oh4eI3S9OueVV41AgJ1oLjpaJUhbJ7JDGOMhe0AFqoSejl5Q2nn3eGglAzRUKVKZE8jG5MNn66TjCJMAnpsWA==
   dependencies:
-    debug "^3.1.0"
+    debug "=3.1.0"
 
 font-awesome@^4.7.0:
   version "4.7.0"
   resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
+  integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=
 
 for-in@^0.1.3:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
+  integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=
 
-for-in@^1.0.1:
+for-in@^1.0.1, for-in@^1.0.2:
   version "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"
+  integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=
   dependencies:
     for-in "^1.0.1"
 
-foreach@^2.0.5:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
-
 forever-agent@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+  integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
 
-form-data@~2.1.1:
-  version "2.1.4"
-  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
-  dependencies:
-    asynckit "^0.4.0"
-    combined-stream "^1.0.5"
-    mime-types "^2.1.12"
-
-form-data@~2.3.1:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
+form-data@~2.3.2:
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
+  integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
   dependencies:
     asynckit "^0.4.0"
-    combined-stream "^1.0.5"
+    combined-stream "^1.0.6"
     mime-types "^2.1.12"
 
 forwarded@~0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
+  integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
 
-fraction.js@4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.2.tgz#0eae896626f334b1bde763371347a83b5575d7f0"
+fragment-cache@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
+  integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=
+  dependencies:
+    map-cache "^0.2.2"
 
 fresh@0.5.2:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
+  integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
 
-from@~0:
-  version "0.1.7"
-  resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
+from2@^2.1.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
+  integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=
+  dependencies:
+    inherits "^2.0.1"
+    readable-stream "^2.0.0"
+
+fs-minipass@^1.2.5:
+  version "1.2.5"
+  resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
+  integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==
+  dependencies:
+    minipass "^2.2.1"
 
-fs-extra@^0.30.0:
-  version "0.30.0"
-  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
+fs-write-stream-atomic@^1.0.8:
+  version "1.0.10"
+  resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
+  integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=
   dependencies:
     graceful-fs "^4.1.2"
-    jsonfile "^2.1.0"
-    klaw "^1.0.0"
-    path-is-absolute "^1.0.0"
-    rimraf "^2.2.8"
+    iferr "^0.1.5"
+    imurmurhash "^0.1.4"
+    readable-stream "1 || 2"
 
 fs.realpath@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+  integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
 
-fsevents@*, fsevents@^1.0.0, fsevents@^1.1.1:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8"
-  dependencies:
-    nan "^2.3.0"
-    node-pre-gyp "^0.6.39"
-
-fstream-ignore@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
-  dependencies:
-    fstream "^1.0.0"
-    inherits "2"
-    minimatch "^3.0.0"
-
-fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2:
-  version "1.0.11"
-  resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171"
+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==
   dependencies:
-    graceful-fs "^4.1.2"
-    inherits "~2.0.0"
-    mkdirp ">=0.5 0"
-    rimraf "2"
+    nan "^2.9.2"
+    node-pre-gyp "^0.10.0"
 
 function-bind@^1.0.2, function-bind@^1.1.0, 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==
 
-function.prototype.name@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.0.3.tgz#0099ae5572e9dd6f03c97d023fd92bcc5e639eac"
+function.prototype.name@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
+  integrity sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==
   dependencies:
     define-properties "^1.1.2"
-    function-bind "^1.1.0"
+    function-bind "^1.1.1"
     is-callable "^1.1.3"
 
 functional-red-black-tree@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
+  integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
 
 gauge@~2.7.3:
   version "2.7.4"
   resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
+  integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
   dependencies:
     aproba "^1.0.3"
     console-control-strings "^1.0.0"
@@ -3063,47 +3945,44 @@ gauge@~2.7.3:
     strip-ansi "^3.0.1"
     wide-align "^1.1.0"
 
-gaze@^1.0.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105"
-  dependencies:
-    globule "^1.0.0"
-
-generate-function@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
-
-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"
-  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"
+  integrity sha1-eAw29p360FpaBF3Te+etyhGk9v8=
 
 get-caller-file@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"
-
-get-stdin@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
+  version "1.0.3"
+  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"
+  integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
+  dependencies:
+    pump "^3.0.0"
+
+get-value@^2.0.3, get-value@^2.0.6:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
+  integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
 
 getpass@^0.1.1:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+  integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
   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"
@@ -3111,22 +3990,22 @@ glob-base@^0.3.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@^6.0.4:
-  version "6.0.4"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
+glob-parent@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
+  integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=
   dependencies:
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "2 || 3"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
+    is-glob "^3.1.0"
+    path-dirname "^1.0.0"
 
-glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1:
-  version "7.1.2"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
+glob@^7.0.3, glob@^7.0.5, 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==
   dependencies:
     fs.realpath "^1.0.0"
     inflight "^1.0.4"
@@ -3135,28 +4014,25 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1:
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-globals@^11.0.1, globals@^11.1.0:
-  version "11.1.0"
-  resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4"
+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==
+
+globals@^11.1.0, 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:
   version "9.18.0"
   resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
-
-globby@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
-  dependencies:
-    array-union "^1.0.1"
-    arrify "^1.0.0"
-    glob "^7.0.3"
-    object-assign "^4.0.1"
-    pify "^2.0.0"
-    pinkie-promise "^2.0.0"
+  integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
 
 globby@^6.1.0:
   version "6.1.0"
   resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
+  integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=
   dependencies:
     array-union "^1.0.1"
     glob "^7.0.3"
@@ -3164,144 +4040,143 @@ globby@^6.1.0:
     pify "^2.0.0"
     pinkie-promise "^2.0.0"
 
-globule@^1.0.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09"
-  dependencies:
-    glob "~7.1.1"
-    lodash "~4.17.4"
-    minimatch "~3.0.2"
-
-gonzales-pe@^4.0.3:
-  version "4.2.3"
-  resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.2.3.tgz#41091703625433285e0aee3aa47829fc1fbeb6f2"
-  dependencies:
-    minimist "1.1.x"
-
-graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
-  version "4.1.11"
-  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2:
+  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==
 
 growly@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
+  integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
 
-gzip-size@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-3.0.0.tgz#546188e9bdc337f673772f81660464b389dce520"
+gzip-size@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80"
+  integrity sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA==
   dependencies:
     duplexer "^0.1.1"
+    pify "^3.0.0"
 
-handle-thing@^1.2.5:
-  version "1.2.5"
-  resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
+handle-thing@^2.0.0:
+  version "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.11"
-  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc"
+  version "4.0.12"
+  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5"
+  integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==
   dependencies:
-    async "^1.4.0"
+    async "^2.5.0"
     optimist "^0.6.1"
-    source-map "^0.4.4"
+    source-map "^0.6.1"
   optionalDependencies:
-    uglify-js "^2.6"
-
-har-schema@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+    uglify-js "^3.1.4"
 
 har-schema@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
+  integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
 
-har-validator@~2.0.6:
-  version "2.0.6"
-  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d"
-  dependencies:
-    chalk "^1.1.1"
-    commander "^2.9.0"
-    is-my-json-valid "^2.12.4"
-    pinkie-promise "^2.0.0"
-
-har-validator@~4.2.1:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
-  dependencies:
-    ajv "^4.9.1"
-    har-schema "^1.0.5"
-
-har-validator@~5.0.3:
-  version "5.0.3"
-  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
+har-validator@~5.1.0:
+  version "5.1.3"
+  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
+  integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
   dependencies:
-    ajv "^5.1.0"
+    ajv "^6.5.5"
     har-schema "^2.0.0"
 
 has-ansi@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+  integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
   dependencies:
     ansi-regex "^2.0.0"
 
 has-flag@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
+  integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
 
-has-flag@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
+has-flag@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+  integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+
+has-symbols@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
+  integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
 
 has-unicode@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
+  integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
 
-has@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
+has-value@^0.3.1:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
+  integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=
   dependencies:
-    function-bind "^1.0.2"
+    get-value "^2.0.3"
+    has-values "^0.1.4"
+    isobject "^2.0.0"
 
-hash-base@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1"
+has-value@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177"
+  integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=
   dependencies:
-    inherits "^2.0.1"
+    get-value "^2.0.6"
+    has-values "^1.0.0"
+    isobject "^3.0.0"
+
+has-values@^0.1.4:
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771"
+  integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E=
+
+has-values@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f"
+  integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=
+  dependencies:
+    is-number "^3.0.0"
+    kind-of "^4.0.0"
+
+has@^1.0.0, has@^1.0.1, has@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
+  integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+  dependencies:
+    function-bind "^1.1.1"
 
 hash-base@^3.0.0:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918"
+  integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=
   dependencies:
     inherits "^2.0.1"
     safe-buffer "^5.0.1"
 
 hash.js@^1.0.0, hash.js@^1.0.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846"
+  version "1.1.7"
+  resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
+  integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
   dependencies:
     inherits "^2.0.3"
-    minimalistic-assert "^1.0.0"
+    minimalistic-assert "^1.0.1"
 
-hawk@3.1.3, hawk@~3.1.3:
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
-  dependencies:
-    boom "2.x.x"
-    cryptiles "2.x.x"
-    hoek "2.x.x"
-    sntp "1.x.x"
-
-hawk@~6.0.2:
-  version "6.0.2"
-  resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
-  dependencies:
-    boom "4.x.x"
-    cryptiles "3.x.x"
-    hoek "4.x.x"
-    sntp "2.x.x"
+hex-color-regex@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
+  integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
 
 history@^4.7.2:
   version "4.7.2"
   resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b"
+  integrity sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==
   dependencies:
     invariant "^2.2.1"
     loose-envify "^1.2.0"
@@ -3312,116 +4187,139 @@ history@^4.7.2:
 hmac-drbg@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
+  integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
   dependencies:
     hash.js "^1.0.3"
     minimalistic-assert "^1.0.0"
     minimalistic-crypto-utils "^1.0.1"
 
-hoek@2.x.x:
-  version "2.16.3"
-  resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
-
-hoek@4.x.x:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
+hoist-non-react-statics@^2.5.0, hoist-non-react-statics@^2.5.5:
+  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@^2.2.1, hoist-non-react-statics@^2.3.0:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
+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==
+  dependencies:
+    react-is "^16.3.2"
 
 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=
   dependencies:
     os-homedir "^1.0.0"
     os-tmpdir "^1.0.1"
 
+hoopy@^0.1.2:
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d"
+  integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==
+
 hosted-git-info@^2.1.4:
-  version "2.5.0"
-  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
+  version "2.7.1"
+  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047"
+  integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==
 
 hpack.js@^2.1.6:
   version "2.1.6"
   resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
+  integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=
   dependencies:
     inherits "^2.0.1"
     obuf "^1.0.0"
     readable-stream "^2.0.1"
     wbuf "^1.1.0"
 
+hsl-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e"
+  integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=
+
+hsla-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38"
+  integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg=
+
 html-comment-regex@^1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e"
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7"
+  integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
 
-html-encoding-sniffer@^1.0.1:
+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"
+  integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==
   dependencies:
     whatwg-encoding "^1.0.1"
 
 html-entities@^1.2.0:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
+  integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=
 
 htmlparser2@^3.9.1:
-  version "3.9.2"
-  resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
+  version "3.10.0"
+  resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464"
+  integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==
   dependencies:
     domelementtype "^1.3.0"
     domhandler "^2.3.0"
     domutils "^1.5.1"
     entities "^1.1.1"
     inherits "^2.0.1"
-    readable-stream "^2.0.2"
+    readable-stream "^3.0.6"
 
 http-deceiver@^1.2.7:
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
+  integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
 
-http-errors@1.6.2, http-errors@~1.6.2:
-  version "1.6.2"
-  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
+http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3:
+  version "1.6.3"
+  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
+  integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
   dependencies:
-    depd "1.1.1"
+    depd "~1.1.2"
     inherits "2.0.3"
-    setprototypeof "1.0.3"
-    statuses ">= 1.3.1 < 2"
+    setprototypeof "1.1.0"
+    statuses ">= 1.4.0 < 2"
 
-http-link-header@^0.8.0:
-  version "0.8.0"
-  resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-0.8.0.tgz#a22b41a0c9b1e2d8fac1bf1b697c6bd532d5f5e4"
+http-link-header@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-1.0.2.tgz#bea50f02e1c7996021f1013b428c63f77e0f4e11"
+  integrity sha512-z6YOZ8ZEnejkcCWlGZzYXNa6i+ZaTfiTg3WhlV/YvnNya3W/RbX1bMVUMTuCrg/DrtTCQxaFCkXCz4FtLpcebg==
 
 http-parser-js@>=0.4.0:
-  version "0.4.9"
-  resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.9.tgz#ea1a04fb64adff0242e9974f297dd4c3cad271e1"
+  version "0.5.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.17.4:
-  version "0.17.4"
-  resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833"
+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==
   dependencies:
     http-proxy "^1.16.2"
-    is-glob "^3.1.0"
-    lodash "^4.17.2"
-    micromatch "^2.3.11"
+    is-glob "^4.0.0"
+    lodash "^4.17.5"
+    micromatch "^3.1.9"
 
 http-proxy@^1.16.2:
-  version "1.16.2"
-  resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742"
-  dependencies:
-    eventemitter3 "1.x.x"
-    requires-port "1.x.x"
-
-http-signature@~1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+  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==
   dependencies:
-    assert-plus "^0.2.0"
-    jsprim "^1.2.2"
-    sshpk "^1.7.0"
+    eventemitter3 "^3.0.0"
+    follow-redirects "^1.0.0"
+    requires-port "^1.0.0"
 
 http-signature@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
+  integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
   dependencies:
     assert-plus "^1.0.0"
     jsprim "^1.2.2"
@@ -3430,43 +4328,103 @@ http-signature@~1.2.0:
 https-browserify@^1.0.0:
   version "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.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13:
-  version "0.4.19"
-  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
+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"
+  integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
+  dependencies:
+    safer-buffer ">= 2.1.2 < 3"
 
 icss-replace-symbols@^1.1.0:
   version "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==
+  dependencies:
+    postcss "^7.0.5"
+
+ieee754@^1.1.4:
+  version "1.1.12"
+  resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b"
+  integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==
+
+iferr@^0.1.5:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
+  integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE=
+
+ignore-walk@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8"
+  integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==
+  dependencies:
+    minimatch "^3.0.4"
+
+ignore@^4.0.6:
+  version "4.0.6"
+  resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
+  integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
+
+immutable@^3.8.2:
+  version "3.8.2"
+  resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3"
+  integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=
+
+import-cwd@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
+  integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=
+  dependencies:
+    import-from "^2.1.0"
+
+import-fresh@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
+  integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY=
+  dependencies:
+    caller-path "^2.0.0"
+    resolve-from "^3.0.0"
 
-icss-utils@^2.1.0:
+import-from@^2.1.0:
   version "2.1.0"
-  resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962"
+  resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1"
+  integrity sha1-M1238qev/VOqpHHUuAId7ja387E=
   dependencies:
-    postcss "^6.0.1"
-
-ieee754@^1.1.4:
-  version "1.1.8"
-  resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
-
-ignore@^3.3.3:
-  version "3.3.7"
-  resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021"
-
-immutable@^3.8.2:
-  version "3.8.2"
-  resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3"
+    resolve-from "^3.0.0"
 
-import-local@^0.1.1:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/import-local/-/import-local-0.1.1.tgz#b1179572aacdc11c6a91009fb430dbcab5f668a8"
+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"
+  integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==
+  dependencies:
+    pkg-dir "^3.0.0"
+    resolve-cwd "^2.0.0"
+
 imports-loader@^0.8.0:
   version "0.8.0"
   resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-0.8.0.tgz#030ea51b8ca05977c40a3abfd9b4088fe0be9a69"
+  integrity sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==
   dependencies:
     loader-utils "^1.0.2"
     source-map "^0.6.1"
@@ -3474,349 +4432,511 @@ imports-loader@^0.8.0:
 imurmurhash@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
-
-in-publish@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51"
-
-indent-string@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
-  dependencies:
-    repeating "^2.0.0"
+  integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
 
 indexes-of@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
+  integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
 
 indexof@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
+  integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
 
 inflight@^1.0.4:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+  integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
   dependencies:
     once "^1.3.0"
     wrappy "1"
 
-inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
+inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+  integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
 
 inherits@2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+  integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
 
 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@^3.0.6:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
+inquirer@^6.1.0:
+  version "6.2.1"
+  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52"
+  integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==
   dependencies:
     ansi-escapes "^3.0.0"
     chalk "^2.0.0"
     cli-cursor "^2.1.0"
     cli-width "^2.0.0"
-    external-editor "^2.0.4"
+    external-editor "^3.0.0"
     figures "^2.0.0"
-    lodash "^4.3.0"
+    lodash "^4.17.10"
     mute-stream "0.0.7"
     run-async "^2.2.0"
-    rx-lite "^4.0.8"
-    rx-lite-aggregates "^4.0.8"
+    rxjs "^6.1.0"
     string-width "^2.1.0"
-    strip-ansi "^4.0.0"
+    strip-ansi "^5.0.0"
     through "^2.3.6"
 
-internal-ip@1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c"
+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==
   dependencies:
-    meow "^3.3.0"
+    default-gateway "^2.6.0"
+    ipaddr.js "^1.5.2"
 
-interpret@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
+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.0:
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.5.0.tgz#9fe8bee3953c755b1485c38efd9633d535775ea6"
+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==
 
 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:
   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@^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"
+  integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw=
   dependencies:
     intl-messageformat-parser "1.4.0"
 
-intl-relativeformat@^2.0.0, intl-relativeformat@^2.1.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=
   dependencies:
     intl-messageformat "^2.0.0"
 
 intl@^1.2.5:
   version "1.2.5"
   resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde"
+  integrity sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94=
 
-invariant@^2.0.0, invariant@^2.1.1, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
-  version "2.2.2"
-  resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
+invariant@^2.1.1, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4:
+  version "2.2.4"
+  resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
+  integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
   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"
+  integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
+
+ip-regex@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
+  integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
 
 ip@^1.1.0, ip@^1.1.5:
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
+  integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
 
-ipaddr.js@1.5.2:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0"
+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=
 
 is-absolute-url@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
+  integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=
+
+is-accessor-descriptor@^0.1.6:
+  version "0.1.6"
+  resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
+  integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=
+  dependencies:
+    kind-of "^3.0.2"
+
+is-accessor-descriptor@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656"
+  integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==
+  dependencies:
+    kind-of "^6.0.0"
 
 is-arrayish@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+  integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
+
+is-arrayish@^0.3.1:
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
+  integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
 
 is-binary-path@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
+  integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=
   dependencies:
     binary-extensions "^1.0.0"
 
-is-buffer@^1.0.2, is-buffer@^1.1.5:
+is-boolean-object@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
+  integrity sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=
+
+is-buffer@^1.1.5:
   version "1.1.6"
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
+  integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
 
 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"
+  integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74=
   dependencies:
     builtin-modules "^1.0.0"
 
-is-callable@^1.1.1, is-callable@^1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
+is-callable@^1.1.3, is-callable@^1.1.4:
+  version "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.0.10"
-  resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e"
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
+  integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==
+  dependencies:
+    ci-info "^1.5.0"
+
+is-color-stop@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345"
+  integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=
+  dependencies:
+    css-color-names "^0.0.4"
+    hex-color-regex "^1.1.0"
+    hsl-regex "^1.0.0"
+    hsla-regex "^1.0.0"
+    rgb-regex "^1.0.1"
+    rgba-regex "^1.0.0"
+
+is-data-descriptor@^0.1.4:
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
+  integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=
+  dependencies:
+    kind-of "^3.0.2"
+
+is-data-descriptor@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7"
+  integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==
   dependencies:
-    ci-info "^1.0.0"
+    kind-of "^6.0.0"
 
 is-date-object@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
+  integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=
+
+is-descriptor@^0.1.0:
+  version "0.1.6"
+  resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
+  integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==
+  dependencies:
+    is-accessor-descriptor "^0.1.6"
+    is-data-descriptor "^0.1.4"
+    kind-of "^5.0.0"
+
+is-descriptor@^1.0.0, is-descriptor@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec"
+  integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==
+  dependencies:
+    is-accessor-descriptor "^1.0.0"
+    is-data-descriptor "^1.0.0"
+    kind-of "^6.0.2"
 
 is-directory@^0.3.1:
   version "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.1:
+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"
+  integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=
+
+is-extendable@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4"
+  integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==
+  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.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"
+  integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
   dependencies:
     number-is-nan "^1.0.0"
 
 is-fullwidth-code-point@^2.0.0:
   version "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-glob@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
+  integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=
   dependencies:
     is-extglob "^2.1.0"
 
-is-my-json-valid@^2.12.4:
-  version "2.16.1"
-  resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11"
+is-glob@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0"
+  integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=
   dependencies:
-    generate-function "^2.0.0"
-    generate-object-property "^1.1.0"
-    jsonpointer "^4.0.0"
-    xtend "^4.0.0"
+    is-extglob "^2.1.1"
 
 is-nan@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.2.1.tgz#9faf65b6fb6db24b7f5c0628475ea71f988401e2"
+  integrity sha1-n69ltvttskt/XAYoR16nH5iEAeI=
   dependencies:
     define-properties "^1.1.1"
 
+is-number-object@^1.0.3:
+  version "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"
+  integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=
   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-in-cwd@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc"
+  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==
   dependencies:
     is-path-inside "^1.0.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=
   dependencies:
     path-is-inside "^1.0.1"
 
-is-plain-obj@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
-
-is-plain-object@^2.0.1:
+is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
+  integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
   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"
-
-is-property@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
+  integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
 
 is-regex@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
+  integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=
   dependencies:
     has "^1.0.1"
 
 is-resolvable@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4"
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
+  integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
 
 is-stream@^1.0.1, is-stream@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+  integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+
+is-string@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64"
+  integrity sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=
 
 is-subset@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
+  integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=
 
-is-svg@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9"
+is-svg@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75"
+  integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==
   dependencies:
     html-comment-regex "^1.1.0"
 
-is-symbol@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
+is-symbol@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
+  integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==
+  dependencies:
+    has-symbols "^1.0.0"
 
 is-typedarray@~1.0.0:
   version "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:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9"
+is-windows@^1.0.0, 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==
 
 is-wsl@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
+  integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=
 
 isarray@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+  integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
 
 isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+  integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
 
 isexe@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+  integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
 
 isobject@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
+  integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=
   dependencies:
     isarray "1.0.0"
 
-isobject@^3.0.1:
+isobject@^3.0.0, isobject@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
+  integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
 
 isomorphic-fetch@^2.1.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+  integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
   dependencies:
     node-fetch "^1.0.1"
     whatwg-fetch ">=0.10.0"
@@ -3824,485 +4944,630 @@ isomorphic-fetch@^2.1.1:
 isstream@~0.1.2:
   version "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.1.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.2.1.tgz#0c60a0515eb11c7d65c6b50bba2c6e999acd8620"
+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.1.1"
-    istanbul-lib-hook "^1.1.0"
-    istanbul-lib-instrument "^1.9.1"
-    istanbul-lib-report "^1.1.2"
-    istanbul-lib-source-maps "^1.2.2"
-    istanbul-reports "^1.1.3"
+    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.0.1, istanbul-lib-coverage@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da"
+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-hook@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b"
+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.4.2, istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.9.1:
-  version "1.9.1"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e"
+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.1.1"
+    istanbul-lib-coverage "^1.2.1"
     semver "^5.3.0"
 
-istanbul-lib-report@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425"
+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==
   dependencies:
-    istanbul-lib-coverage "^1.1.1"
+    istanbul-lib-coverage "^1.2.1"
     mkdirp "^0.5.1"
     path-parse "^1.0.5"
     supports-color "^3.1.2"
 
-istanbul-lib-source-maps@^1.1.0, istanbul-lib-source-maps@^1.2.2:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c"
+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==
   dependencies:
     debug "^3.1.0"
-    istanbul-lib-coverage "^1.1.1"
+    istanbul-lib-coverage "^1.2.1"
     mkdirp "^0.5.1"
     rimraf "^2.6.1"
     source-map "^0.5.3"
 
-istanbul-reports@^1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10"
+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==
   dependencies:
     handlebars "^4.0.3"
 
-javascript-natural-sort@0.7.1:
-  version "0.7.1"
-  resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59"
-
-jest-changed-files@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-21.2.0.tgz#5dbeecad42f5d88b482334902ce1cba6d9798d29"
+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==
   dependencies:
     throat "^4.0.0"
 
-jest-cli@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-21.2.1.tgz#9c528b6629d651911138d228bdb033c157ec8c00"
+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==
   dependencies:
     ansi-escapes "^3.0.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.1.1"
-    istanbul-lib-coverage "^1.0.1"
-    istanbul-lib-instrument "^1.4.2"
-    istanbul-lib-source-maps "^1.1.0"
-    jest-changed-files "^21.2.0"
-    jest-config "^21.2.1"
-    jest-environment-jsdom "^21.2.1"
-    jest-haste-map "^21.2.0"
-    jest-message-util "^21.2.1"
-    jest-regex-util "^21.2.0"
-    jest-resolve-dependencies "^21.2.0"
-    jest-runner "^21.2.1"
-    jest-runtime "^21.2.1"
-    jest-snapshot "^21.2.1"
-    jest-util "^21.2.1"
+    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.0.2"
-    pify "^3.0.0"
+    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"
-    worker-farm "^1.3.1"
-    yargs "^9.0.0"
+    yargs "^11.0.0"
 
-jest-config@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-21.2.1.tgz#c7586c79ead0bcc1f38c401e55f964f13bf2a480"
+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==
   dependencies:
+    babel-core "^6.0.0"
+    babel-jest "^23.6.0"
     chalk "^2.0.1"
     glob "^7.1.1"
-    jest-environment-jsdom "^21.2.1"
-    jest-environment-node "^21.2.1"
-    jest-get-type "^21.2.0"
-    jest-jasmine2 "^21.2.1"
-    jest-regex-util "^21.2.0"
-    jest-resolve "^21.2.0"
-    jest-util "^21.2.1"
-    jest-validate "^21.2.1"
-    pretty-format "^21.2.1"
-
-jest-diff@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-21.2.1.tgz#46cccb6cab2d02ce98bc314011764bb95b065b4f"
+    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==
   dependencies:
     chalk "^2.0.1"
     diff "^3.2.0"
-    jest-get-type "^21.2.0"
-    pretty-format "^21.2.1"
+    jest-get-type "^22.1.0"
+    pretty-format "^23.6.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=
+  dependencies:
+    detect-newline "^2.1.0"
 
-jest-docblock@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414"
+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==
+  dependencies:
+    chalk "^2.0.1"
+    pretty-format "^23.6.0"
 
-jest-environment-jsdom@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-21.2.1.tgz#38d9980c8259b2a608ec232deee6289a60d9d5b4"
+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 "^21.2.0"
-    jest-util "^21.2.1"
-    jsdom "^9.12.0"
+    jest-mock "^23.2.0"
+    jest-util "^23.4.0"
+    jsdom "^11.5.1"
 
-jest-environment-node@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-21.2.1.tgz#98c67df5663c7fbe20f6e792ac2272c740d3b8c8"
+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=
   dependencies:
-    jest-mock "^21.2.0"
-    jest-util "^21.2.1"
+    jest-mock "^23.2.0"
+    jest-util "^23.4.0"
 
-jest-get-type@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23"
+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-haste-map@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-21.2.0.tgz#1363f0a8bb4338f24f001806571eff7a4b2ff3d8"
+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==
   dependencies:
     fb-watchman "^2.0.0"
     graceful-fs "^4.1.11"
-    jest-docblock "^21.2.0"
+    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"
-    worker-farm "^1.3.1"
 
-jest-jasmine2@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-21.2.1.tgz#9cc6fc108accfa97efebce10c4308548a4ea7592"
+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"
     chalk "^2.0.1"
-    expect "^21.2.1"
-    graceful-fs "^4.1.11"
-    jest-diff "^21.2.1"
-    jest-matcher-utils "^21.2.1"
-    jest-message-util "^21.2.1"
-    jest-snapshot "^21.2.1"
-    p-cancelable "^0.3.0"
-
-jest-matcher-utils@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz#72c826eaba41a093ac2b4565f865eb8475de0f64"
+    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==
   dependencies:
     chalk "^2.0.1"
-    jest-get-type "^21.2.0"
-    pretty-format "^21.2.1"
+    jest-get-type "^22.1.0"
+    pretty-format "^23.6.0"
 
-jest-message-util@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-21.2.1.tgz#bfe5d4692c84c827d1dcf41823795558f0a1acbe"
+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=
   dependencies:
+    "@babel/code-frame" "^7.0.0-beta.35"
     chalk "^2.0.1"
     micromatch "^2.3.11"
     slash "^1.0.0"
+    stack-utils "^1.0.1"
 
-jest-mock@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-21.2.0.tgz#7eb0770e7317968165f61ea2a7281131534b3c0f"
+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-regex-util@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-21.2.0.tgz#1b1e33e63143babc3e0f2e6c9b5ba1eb34b2d530"
+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-resolve-dependencies@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-21.2.0.tgz#9e231e371e1a736a1ad4e4b9a843bc72bfe03d09"
+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==
   dependencies:
-    jest-regex-util "^21.2.0"
+    jest-regex-util "^23.3.0"
+    jest-snapshot "^23.6.0"
 
-jest-resolve@^21.2.0:
-  version "21.2.0"
-  resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-21.2.0.tgz#068913ad2ba6a20218e5fd32471f3874005de3a6"
+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==
   dependencies:
-    browser-resolve "^1.11.2"
+    browser-resolve "^1.11.3"
     chalk "^2.0.1"
-    is-builtin-module "^1.0.0"
+    realpath-native "^1.0.0"
 
-jest-runner@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-21.2.1.tgz#194732e3e518bfb3d7cbfc0fd5871246c7e1a467"
-  dependencies:
-    jest-config "^21.2.1"
-    jest-docblock "^21.2.0"
-    jest-haste-map "^21.2.0"
-    jest-jasmine2 "^21.2.1"
-    jest-message-util "^21.2.1"
-    jest-runtime "^21.2.1"
-    jest-util "^21.2.1"
-    pify "^3.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:
+    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"
+    source-map-support "^0.5.6"
     throat "^4.0.0"
-    worker-farm "^1.3.1"
 
-jest-runtime@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-21.2.1.tgz#99dce15309c670442eee2ebe1ff53a3cbdbbb73e"
+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-jest "^21.2.0"
-    babel-plugin-istanbul "^4.0.0"
+    babel-plugin-istanbul "^4.1.6"
     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 "^21.2.1"
-    jest-haste-map "^21.2.0"
-    jest-regex-util "^21.2.0"
-    jest-resolve "^21.2.0"
-    jest-util "^21.2.1"
-    json-stable-stringify "^1.0.1"
+    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 "^9.0.0"
+    yargs "^11.0.0"
+
+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-snapshot@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-21.2.1.tgz#29e49f16202416e47343e757e5eff948c07fd7b0"
+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==
   dependencies:
+    babel-types "^6.0.0"
     chalk "^2.0.1"
-    jest-diff "^21.2.1"
-    jest-matcher-utils "^21.2.1"
+    jest-diff "^23.6.0"
+    jest-matcher-utils "^23.6.0"
+    jest-message-util "^23.4.0"
+    jest-resolve "^23.6.0"
     mkdirp "^0.5.1"
     natural-compare "^1.4.0"
-    pretty-format "^21.2.1"
+    pretty-format "^23.6.0"
+    semver "^5.5.0"
 
-jest-util@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-21.2.1.tgz#a274b2f726b0897494d694a6c3d6a61ab819bb78"
+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"
     chalk "^2.0.1"
     graceful-fs "^4.1.11"
-    jest-message-util "^21.2.1"
-    jest-mock "^21.2.0"
-    jest-validate "^21.2.1"
+    is-ci "^1.0.10"
+    jest-message-util "^23.4.0"
     mkdirp "^0.5.1"
+    slash "^1.0.0"
+    source-map "^0.6.0"
 
-jest-validate@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-21.2.1.tgz#cc0cbca653cd54937ba4f2a111796774530dd3c7"
+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==
   dependencies:
     chalk "^2.0.1"
-    jest-get-type "^21.2.0"
+    jest-get-type "^22.1.0"
     leven "^2.1.0"
-    pretty-format "^21.2.1"
+    pretty-format "^23.6.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=
+  dependencies:
+    ansi-escapes "^3.0.0"
+    chalk "^2.0.1"
+    string-length "^2.0.0"
 
-jest@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/jest/-/jest-21.2.1.tgz#c964e0b47383768a1438e3ccf3c3d470327604e1"
+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=
   dependencies:
-    jest-cli "^21.2.1"
+    merge-stream "^1.0.1"
 
-js-base64@^2.1.8, js-base64@^2.1.9:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"
+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==
+  dependencies:
+    import-local "^1.0.0"
+    jest-cli "^23.6.0"
+
+js-base64@^2.1.9:
+  version "2.5.0"
+  resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.0.tgz#42255ba183ab67ce59a0dee640afdc00ab5ae93e"
+  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==
 
 js-string-escape@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef"
+  integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=
+
+"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+  integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
 
-js-tokens@^3.0.0, js-tokens@^3.0.2:
+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.4.3, js-yaml@^3.7.0, js-yaml@^3.9.0, js-yaml@^3.9.1:
-  version "3.10.0"
-  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
+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==
   dependencies:
     argparse "^1.0.7"
     esprima "^4.0.0"
 
-js-yaml@~3.7.0:
-  version "3.7.0"
-  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
-  dependencies:
-    argparse "^1.0.7"
-    esprima "^2.6.0"
-
 jsbn@~0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+  integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
 
-jsdom@^9.12.0:
-  version "9.12.0"
-  resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4"
+jsdom@^11.5.1:
+  version "11.12.0"
+  resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8"
+  integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==
   dependencies:
-    abab "^1.0.3"
-    acorn "^4.0.4"
-    acorn-globals "^3.1.0"
+    abab "^2.0.0"
+    acorn "^5.5.3"
+    acorn-globals "^4.1.0"
     array-equal "^1.0.0"
-    content-type-parser "^1.0.1"
     cssom ">= 0.3.2 < 0.4.0"
-    cssstyle ">= 0.2.37 < 0.3.0"
-    escodegen "^1.6.1"
-    html-encoding-sniffer "^1.0.1"
-    nwmatcher ">= 1.3.9 < 2.0.0"
-    parse5 "^1.5.1"
-    request "^2.79.0"
-    sax "^1.2.1"
-    symbol-tree "^3.2.1"
-    tough-cookie "^2.3.2"
-    webidl-conversions "^4.0.0"
-    whatwg-encoding "^1.0.1"
-    whatwg-url "^4.3.0"
-    xml-name-validator "^2.0.1"
+    cssstyle "^1.0.0"
+    data-urls "^1.0.0"
+    domexception "^1.0.1"
+    escodegen "^1.9.1"
+    html-encoding-sniffer "^1.0.2"
+    left-pad "^1.3.0"
+    nwsapi "^2.0.7"
+    parse5 "4.0.0"
+    pn "^1.1.0"
+    request "^2.87.0"
+    request-promise-native "^1.0.5"
+    sax "^1.2.4"
+    symbol-tree "^3.2.2"
+    tough-cookie "^2.3.4"
+    w3c-hr-time "^1.0.1"
+    webidl-conversions "^4.0.2"
+    whatwg-encoding "^1.0.3"
+    whatwg-mimetype "^2.1.0"
+    whatwg-url "^6.4.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.1"
-  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe"
+  version "2.5.2"
+  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
+  integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
 
 jsesc@~0.5.0:
   version "0.5.0"
   resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
+  integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
 
-json-loader@^0.5.4:
-  version "0.5.7"
-  resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
-
-json-parse-better-errors@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a"
+json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
+  integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
 
-json-schema-traverse@^0.3.0:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
+json-schema-traverse@^0.4.1:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
+  integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
 
 json-schema@0.2.3:
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+  integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
 
 json-stable-stringify-without-jsonify@^1.0.1:
   version "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:
   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=
   dependencies:
     jsonify "~0.0.0"
 
 json-stringify-safe@~5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+  integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
 
 json3@^3.3.2:
   version "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:
   version "0.5.1"
   resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
+  integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
 
-jsonfile@^2.1.0:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
-  optionalDependencies:
-    graceful-fs "^4.1.6"
+json5@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
+  integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
+  dependencies:
+    minimist "^1.2.0"
+
+json5@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
+  integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==
+  dependencies:
+    minimist "^1.2.0"
 
 jsonify@~0.0.0:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
-
-jsonpointer@^4.0.0:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
+  integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
 
 jsprim@^1.2.2:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
+  integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
   dependencies:
     assert-plus "1.0.0"
     extsprintf "1.3.0"
     json-schema "0.2.3"
     verror "1.10.0"
 
-jsx-ast-utils@^2.0.0, jsx-ast-utils@^2.0.1:
+jsx-ast-utils@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
+  integrity sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=
   dependencies:
     array-includes "^3.0.3"
 
 keycode@^2.1.7:
-  version "2.1.9"
-  resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.9.tgz#964a23c54e4889405b4861a5c9f0480d45141dfa"
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
+  integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=
 
 killable@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b"
-
-kind-of@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5"
-  dependencies:
-    is-buffer "^1.0.2"
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
+  integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==
 
-kind-of@^3.0.2, kind-of@^3.2.2:
+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
+  integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=
   dependencies:
     is-buffer "^1.1.5"
 
 kind-of@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
+  integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc=
   dependencies:
     is-buffer "^1.1.5"
 
-klaw@^1.0.0:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
-  optionalDependencies:
-    graceful-fs "^4.1.9"
+kind-of@^5.0.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
+  integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==
 
-lazy-cache@^0.2.3:
-  version "0.2.7"
-  resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65"
+kind-of@^6.0.0, kind-of@^6.0.2:
+  version "6.0.2"
+  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
+  integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==
 
-lazy-cache@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
+kleur@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300"
+  integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ==
+
+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"
 
+lcid@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
+  integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
+  dependencies:
+    invert-kv "^2.0.0"
+
+left-pad@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
+  integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==
+
 leven@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
+  integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA=
 
 levn@^0.3.0, levn@~0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
+  integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
   dependencies:
     prelude-ls "~1.1.2"
     type-check "~0.3.2"
@@ -4310,6 +5575,7 @@ levn@^0.3.0, levn@~0.3.0:
 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"
@@ -4320,301 +5586,272 @@ load-json-file@^1.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"
+  integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=
   dependencies:
     graceful-fs "^4.1.2"
     parse-json "^2.2.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"
-  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.0"
-  resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979"
+  integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw==
 
 loader-utils@0.2.x:
   version "0.2.17"
   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
+  integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=
   dependencies:
     big.js "^3.1.3"
     emojis-list "^2.0.0"
     json5 "^0.5.0"
     object-assign "^4.0.1"
 
-loader-utils@^1.0.0, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
+loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.1:
+  version "1.2.3"
+  resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7"
+  integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==
   dependencies:
-    big.js "^3.1.3"
+    big.js "^5.2.2"
     emojis-list "^2.0.0"
-    json5 "^0.5.0"
+    json5 "^1.0.1"
 
 locate-path@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
+  integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
   dependencies:
     p-locate "^2.0.0"
     path-exists "^3.0.0"
 
-lodash-es@^4.2.0, lodash-es@^4.2.1:
-  version "4.17.4"
-  resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7"
-
-lodash._baseassign@^3.0.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
-  dependencies:
-    lodash._basecopy "^3.0.0"
-    lodash.keys "^3.0.0"
-
-lodash._basecopy@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
-
-lodash._bindcallback@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
-
-lodash._createassigner@^3.0.0:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11"
-  dependencies:
-    lodash._bindcallback "^3.0.0"
-    lodash._isiterateecall "^3.0.0"
-    lodash.restparam "^3.0.0"
-
-lodash._getnative@^3.0.0:
-  version "3.9.1"
-  resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
-
-lodash._isiterateecall@^3.0.0:
-  version "3.0.9"
-  resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
-
-lodash.assign@^3.0.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa"
+locate-path@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
+  integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
   dependencies:
-    lodash._baseassign "^3.0.0"
-    lodash._createassigner "^3.0.0"
-    lodash.keys "^3.0.0"
-
-lodash.assign@^4.0.1, lodash.assign@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
-
-lodash.camelcase@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
-
-lodash.clonedeep@^4.3.2:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
-
-lodash.cond@^4.3.0:
-  version "4.5.2"
-  resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5"
+    p-locate "^3.0.0"
+    path-exists "^3.0.0"
 
-lodash.defaults@^3.1.2:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-3.1.2.tgz#c7308b18dbf8bc9372d701a73493c61192bd2e2c"
-  dependencies:
-    lodash.assign "^3.0.0"
-    lodash.restparam "^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.defaults@^4.0.0, lodash.defaults@^4.0.1:
+lodash.defaults@^4.0.1:
   version "4.2.0"
   resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
+  integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
+
+lodash.escape@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
+  integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=
 
 lodash.flattendeep@^4.4.0:
   version "4.4.0"
   resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
+  integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
 
-lodash.isarguments@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
+lodash.get@^4.0:
+  version "4.4.2"
+  resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+  integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
 
-lodash.isarray@^3.0.0:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
+lodash.has@^4.0:
+  version "4.5.2"
+  resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862"
+  integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=
 
-lodash.keys@^3.0.0:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
-  dependencies:
-    lodash._getnative "^3.0.0"
-    lodash.isarguments "^3.0.0"
-    lodash.isarray "^3.0.0"
+lodash.isboolean@^3.0.3:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
+  integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
+
+lodash.isequal@^4.5.0:
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
+  integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
+
+lodash.isobject@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d"
+  integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=
 
 lodash.memoize@^4.1.2:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
-
-lodash.mergewith@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55"
-
-lodash.restparam@^3.0.0:
-  version "3.6.1"
-  resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
+  integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
 
 lodash.sortby@^4.7.0:
   version "4.7.0"
   resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
+  integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
 
 lodash.tail@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
+  integrity sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=
 
 lodash.uniq@^4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
+  integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
 
-"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.4:
-  version "4.17.4"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+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:
+  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.0"
-  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934"
-
-longest@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
-
-loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
-  dependencies:
-    js-tokens "^3.0.0"
+  version "1.6.1"
+  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
+  integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=
 
-loud-rejection@^1.0.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
+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"
+  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+  integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
   dependencies:
-    currently-unhandled "^0.4.1"
-    signal-exit "^3.0.0"
+    js-tokens "^3.0.0 || ^4.0.0"
 
 lru-cache@^4.0.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
+  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"
 
-macaddress@^0.2.8:
-  version "0.2.8"
-  resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"
+lru-cache@^5.1.1:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
+  integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
+  dependencies:
+    yallist "^3.0.2"
 
 make-dir@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51"
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
+  integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
   dependencies:
     pify "^3.0.0"
 
 makeerror@1.0.x:
   version "1.0.11"
   resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
+  integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=
   dependencies:
     tmpl "1.0.x"
 
-map-obj@^1.0.0, map-obj@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
+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"
+  integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
+  dependencies:
+    p-defer "^1.0.0"
 
-map-stream@~0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
+map-cache@^0.2.2:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
+  integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=
+
+map-visit@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
+  integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=
+  dependencies:
+    object-visit "^1.0.0"
 
 mark-loader@^0.1.6:
   version "0.1.6"
   resolved "https://registry.yarnpkg.com/mark-loader/-/mark-loader-0.1.6.tgz#0abb477dca7421d70e20128ff6489f5cae8676d5"
+  integrity sha1-CrtHfcp0IdcOIBKP9kifXK6GdtU=
 
-marky@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.0.tgz#9617ed647bbbea8f45d19526da33dec70606df42"
-
-math-expression-evaluator@^1.2.14:
-  version "1.2.17"
-  resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
+marky@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.1.tgz#a3fcf82ffd357756b8b8affec9fdbf3a30dc1b02"
+  integrity sha512-md9k+Gxa3qLH6sUKpeC2CNkJK/Ld+bEz5X96nYwloqphQE0CKCVEKco/6jxEZixinqNdz5RFi/KaCyfbMDMAXQ==
 
-mathjs@^3.11.5:
-  version "3.17.0"
-  resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-3.17.0.tgz#9569d278874546175c9d0497d7417eb88fb61503"
-  dependencies:
-    complex.js "2.0.4"
-    decimal.js "7.2.3"
-    fraction.js "4.0.2"
-    javascript-natural-sort "0.7.1"
-    seed-random "2.2.0"
-    tiny-emitter "2.0.0"
-    typed-function "0.10.6"
+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.4"
-  resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
+  version "1.3.5"
+  resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
+  integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==
   dependencies:
     hash-base "^3.0.0"
     inherits "^2.0.1"
+    safe-buffer "^5.1.2"
+
+mdn-data@~1.1.0:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01"
+  integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==
 
 media-typer@0.3.0:
   version "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"
+  integrity sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==
   dependencies:
+    map-age-cleaner "^0.1.1"
     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==
 
 memory-fs@^0.4.0, 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=
   dependencies:
     errno "^0.1.3"
     readable-stream "^2.0.1"
 
-memorystream@^0.3.1:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
-
-meow@^3.3.0, meow@^3.7.0:
-  version "3.7.0"
-  resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
-  dependencies:
-    camelcase-keys "^2.0.0"
-    decamelize "^1.1.2"
-    loud-rejection "^1.0.0"
-    map-obj "^1.0.1"
-    minimist "^1.1.3"
-    normalize-package-data "^2.3.4"
-    object-assign "^4.0.1"
-    read-pkg-up "^1.0.1"
-    redent "^1.0.0"
-    trim-newlines "^1.0.0"
-
 merge-descriptors@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
+  integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
 
-merge@^1.1.3:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da"
+merge-stream@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1"
+  integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=
+  dependencies:
+    readable-stream "^2.0.1"
+
+merge@^1.2.0:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145"
+  integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==
 
 methods@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
+  integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
 
-micromatch@^2.1.5, micromatch@^2.3.11:
+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"
@@ -4630,161 +5867,294 @@ micromatch@^2.1.5, micromatch@^2.3.11:
     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:
+  version "3.1.10"
+  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
+  integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
+  dependencies:
+    arr-diff "^4.0.0"
+    array-unique "^0.3.2"
+    braces "^2.3.1"
+    define-property "^2.0.2"
+    extend-shallow "^3.0.2"
+    extglob "^2.0.4"
+    fragment-cache "^0.2.1"
+    kind-of "^6.0.2"
+    nanomatch "^1.2.9"
+    object.pick "^1.3.0"
+    regex-not "^1.0.0"
+    snapdragon "^0.8.1"
+    to-regex "^3.0.2"
+
 miller-rabin@^4.0.0:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
+  integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
   dependencies:
     bn.js "^4.0.0"
     brorand "^1.0.1"
 
-"mime-db@>= 1.30.0 < 2":
-  version "1.32.0"
-  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.32.0.tgz#485b3848b01a3cda5f968b4882c0771e58e09414"
-
-mime-db@~1.30.0:
-  version "1.30.0"
-  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
+"mime-db@>= 1.36.0 < 2", 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.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7:
-  version "2.1.17"
-  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
+mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, 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.30.0"
+    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@^1.5.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
+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==
 
 mimic-fn@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
+  integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
 
-minimalistic-assert@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
+mini-css-extract-plugin@^0.5.0:
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz#ac0059b02b9692515a637115b0cc9fed3a35c7b0"
+  integrity sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==
+  dependencies:
+    loader-utils "^1.1.0"
+    schema-utils "^1.0.0"
+    webpack-sources "^1.1.0"
+
+minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
+  integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
 
 minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
+  integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
 
-"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
+minimatch@^3.0.3, minimatch@^3.0.4:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
   dependencies:
     brace-expansion "^1.1.7"
 
 minimist@0.0.8:
   version "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"
-
-minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
+minimist@^1.1.1, minimist@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+  integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
 
 minimist@~0.0.1:
   version "0.0.10"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
+  integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
+
+minipass@^2.2.1, minipass@^2.3.4:
+  version "2.3.5"
+  resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848"
+  integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==
+  dependencies:
+    safe-buffer "^5.1.2"
+    yallist "^3.0.0"
+
+minizlib@^1.1.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614"
+  integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==
+  dependencies:
+    minipass "^2.2.1"
+
+mississippi@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
+  integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==
+  dependencies:
+    concat-stream "^1.5.0"
+    duplexify "^3.4.2"
+    end-of-stream "^1.1.0"
+    flush-write-stream "^1.0.0"
+    from2 "^2.1.0"
+    parallel-transform "^1.1.0"
+    pump "^3.0.0"
+    pumpify "^1.3.3"
+    stream-each "^1.1.0"
+    through2 "^2.0.0"
+
+mixin-deep@^1.2.0:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe"
+  integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==
+  dependencies:
+    for-in "^1.0.2"
+    is-extendable "^1.0.1"
 
 mixin-object@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e"
+  integrity sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=
   dependencies:
     for-in "^0.1.3"
     is-extendable "^0.1.1"
 
-mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
+mkdirp@0.5.x, mkdirp@^0.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
   version "0.5.1"
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+  integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
   dependencies:
     minimist "0.0.8"
 
+moo@^0.4.3:
+  version "0.4.3"
+  resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e"
+  integrity sha512-gFD2xGCl8YFgGHsqJ9NKRVdwlioeW3mI1iqfLNYQOv0+6JRwG58Zk9DIGQgyIaffSYaO1xsKnMaYzzNr1KyIAw==
+
 mousetrap@^1.5.2:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.1.tgz#2a085f5c751294c75e7e81f6ec2545b29cbf42d9"
+  version "1.6.2"
+  resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.2.tgz#caadd9cf886db0986fb2fee59a82f6bd37527587"
+  integrity sha512-jDjhi7wlHwdO6q6DS7YRmSHcuI+RVxadBkLt3KHrhd3C2b+w5pKefg3oj5beTcHZyVFA9Aksf+yEE1y5jxUjVA==
+
+move-concurrently@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
+  integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=
+  dependencies:
+    aproba "^1.1.1"
+    copy-concurrently "^1.0.0"
+    fs-write-stream-atomic "^1.0.8"
+    mkdirp "^0.5.1"
+    rimraf "^2.5.4"
+    run-queue "^1.0.3"
 
 ms@2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+  integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
+
+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==
 
 multicast-dns-service-types@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
+  integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=
 
 multicast-dns@^6.0.1:
-  version "6.2.1"
-  resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.1.tgz#c5035defa9219d30640558a49298067352098060"
+  version "6.2.3"
+  resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229"
+  integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==
   dependencies:
-    dns-packet "^1.0.1"
-    thunky "^0.1.0"
+    dns-packet "^1.3.1"
+    thunky "^1.0.2"
 
 mute-stream@0.0.7:
   version "0.0.7"
   resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
-
-nan@^2.0.0, nan@^2.3.0, nan@^2.3.2:
-  version "2.8.0"
-  resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
+  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==
+
+nanomatch@^1.2.9:
+  version "1.2.13"
+  resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
+  integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==
+  dependencies:
+    arr-diff "^4.0.0"
+    array-unique "^0.3.2"
+    define-property "^2.0.2"
+    extend-shallow "^3.0.2"
+    fragment-cache "^0.2.1"
+    is-windows "^1.0.2"
+    kind-of "^6.0.2"
+    object.pick "^1.3.0"
+    regex-not "^1.0.0"
+    snapdragon "^0.8.1"
+    to-regex "^3.0.1"
 
 natural-compare@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+  integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
 
 nearley@^2.7.10:
-  version "2.11.0"
-  resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.11.0.tgz#5e626c79a6cd2f6ab9e7e5d5805e7668967757ae"
+  version "2.16.0"
+  resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.16.0.tgz#77c297d041941d268290ec84b739d0ee297e83a7"
+  integrity sha512-Tr9XD3Vt/EujXbZBv6UAHYoLUSMQAxSsTnm9K3koXzjzNWY195NqALeyrzLZBKzAkL3gl92BcSogqrHjD8QuUg==
   dependencies:
-    nomnom "~1.6.2"
+    commander "^2.19.0"
+    moo "^0.4.3"
     railroad-diagrams "^1.0.0"
-    randexp "^0.4.2"
+    randexp "0.4.6"
+    semver "^5.4.1"
+
+needle@^2.2.1:
+  version "2.2.4"
+  resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e"
+  integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA==
+  dependencies:
+    debug "^2.1.2"
+    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=
+
+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:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
+  integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
+
+nice-try@^1.0.4:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
+  integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
 
 node-fetch@^1.0.1:
   version "1.7.3"
   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
+  integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
   dependencies:
     encoding "^0.1.11"
     is-stream "^1.0.1"
 
-node-forge@0.6.33:
-  version "0.6.33"
-  resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.6.33.tgz#463811879f573d45155ad6a9f43dc296e8e85ebc"
-
-node-gyp@^3.3.1:
-  version "3.6.2"
-  resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60"
-  dependencies:
-    fstream "^1.0.0"
-    glob "^7.0.3"
-    graceful-fs "^4.1.2"
-    minimatch "^3.0.2"
-    mkdirp "^0.5.0"
-    nopt "2 || 3"
-    npmlog "0 || 1 || 2 || 3 || 4"
-    osenv "0"
-    request "2"
-    rimraf "2"
-    semver "~5.3.0"
-    tar "^2.0.0"
-    which "1"
+node-forge@0.7.5:
+  version "0.7.5"
+  resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
+  integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==
 
 node-int64@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
+  integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
 
 node-libs-browser@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df"
+  integrity sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==
   dependencies:
     assert "^1.1.1"
     browserify-zlib "^0.2.0"
@@ -4810,229 +6180,251 @@ node-libs-browser@^2.0.0:
     util "^0.10.3"
     vm-browserify "0.0.4"
 
-node-notifier@^5.0.2:
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.1.2.tgz#2fa9e12605fa10009d44549d6fcd8a63dde0e4ff"
+node-notifier@^5.2.1:
+  version "5.3.0"
+  resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01"
+  integrity sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q==
   dependencies:
     growly "^1.3.0"
-    semver "^5.3.0"
-    shellwords "^0.1.0"
-    which "^1.2.12"
+    semver "^5.5.0"
+    shellwords "^0.1.1"
+    which "^1.3.0"
 
-node-pre-gyp@^0.6.39, node-pre-gyp@^0.6.4:
-  version "0.6.39"
-  resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649"
+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==
   dependencies:
     detect-libc "^1.0.2"
-    hawk "3.1.3"
     mkdirp "^0.5.1"
+    needle "^2.2.1"
     nopt "^4.0.1"
+    npm-packlist "^1.1.6"
     npmlog "^4.0.2"
-    rc "^1.1.7"
-    request "2.81.0"
+    rc "^1.2.7"
     rimraf "^2.6.1"
     semver "^5.3.0"
-    tar "^2.2.1"
-    tar-pack "^3.4.0"
-
-node-sass@^4.7.2:
-  version "4.7.2"
-  resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e"
-  dependencies:
-    async-foreach "^0.1.3"
-    chalk "^1.1.1"
-    cross-spawn "^3.0.0"
-    gaze "^1.0.0"
-    get-stdin "^4.0.1"
-    glob "^7.0.3"
-    in-publish "^2.0.0"
-    lodash.assign "^4.2.0"
-    lodash.clonedeep "^4.3.2"
-    lodash.mergewith "^4.6.0"
-    meow "^3.7.0"
-    mkdirp "^0.5.1"
-    nan "^2.3.2"
-    node-gyp "^3.3.1"
-    npmlog "^4.0.0"
-    request "~2.79.0"
-    sass-graph "^2.2.4"
-    stdout-stream "^1.4.0"
-    "true-case-path" "^1.0.2"
-
-node-zopfli@^2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/node-zopfli/-/node-zopfli-2.0.2.tgz#a7a473ae92aaea85d4c68d45bbf2c944c46116b8"
-  dependencies:
-    commander "^2.8.1"
-    defaults "^1.0.2"
-    nan "^2.0.0"
-    node-pre-gyp "^0.6.4"
-
-nomnom@~1.6.2:
-  version "1.6.2"
-  resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971"
-  dependencies:
-    colors "0.5.x"
-    underscore "~1.4.4"
+    tar "^4"
 
-"nopt@2 || 3":
-  version "3.0.6"
-  resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
+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==
   dependencies:
-    abbrev "1"
+    semver "^5.3.0"
 
 nopt@^4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
+  integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=
   dependencies:
     abbrev "1"
     osenv "^0.1.4"
 
-normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
+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"
+  integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==
   dependencies:
     hosted-git-info "^2.1.4"
     is-builtin-module "^1.0.0"
     semver "2 || 3 || 4 || 5"
     validate-npm-package-license "^3.0.1"
 
-normalize-path@^2.0.0, normalize-path@^2.0.1:
+normalize-path@^2.0.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-range@^0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
+  integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
 
-normalize-url@^1.4.0:
-  version "1.9.1"
-  resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c"
-  dependencies:
-    object-assign "^4.0.1"
-    prepend-http "^1.0.0"
-    query-string "^4.1.0"
-    sort-keys "^1.0.0"
+normalize-url@^3.0.0:
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559"
+  integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==
 
-npm-run-all@^4.1.2:
-  version "4.1.2"
-  resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.2.tgz#90d62d078792d20669139e718621186656cea056"
+npm-bundled@^1.0.1:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979"
+  integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==
+
+npm-packlist@^1.1.6:
+  version "1.1.12"
+  resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a"
+  integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g==
   dependencies:
-    ansi-styles "^3.2.0"
-    chalk "^2.1.0"
-    cross-spawn "^5.1.0"
-    memorystream "^0.3.1"
-    minimatch "^3.0.4"
-    ps-tree "^1.1.0"
-    read-pkg "^3.0.0"
-    shell-quote "^1.6.1"
-    string.prototype.padend "^3.0.0"
+    ignore-walk "^3.0.1"
+    npm-bundled "^1.0.1"
 
 npm-run-path@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
+  integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
   dependencies:
     path-key "^2.0.0"
 
-"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2, npmlog@^4.1.2:
+npmlog@^4.0.2, npmlog@^4.1.2:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
+  integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
   dependencies:
     are-we-there-yet "~1.1.2"
     console-control-strings "~1.1.0"
     gauge "~2.7.3"
     set-blocking "~2.0.0"
 
-nth-check@~1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
+nth-check@^1.0.2, nth-check@~1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
+  integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==
   dependencies:
     boolbase "~1.0.0"
 
 num2fraction@^1.2.2:
   version "1.2.2"
   resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
+  integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
 
 number-is-nan@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+  integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
 
-"nwmatcher@>= 1.3.9 < 2.0.0":
-  version "1.4.3"
-  resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c"
+nwsapi@^2.0.7:
+  version "2.0.9"
+  resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016"
+  integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ==
 
-oauth-sign@~0.8.1, oauth-sign@~0.8.2:
-  version "0.8.2"
-  resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+oauth-sign@~0.9.0:
+  version "0.9.0"
+  resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
+  integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
 
 object-assign@4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0"
+  integrity sha1-ejs9DpgGPUP0wD8uiubNUahog6A=
 
 object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+  integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
+
+object-copy@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
+  integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw=
+  dependencies:
+    copy-descriptor "^0.1.0"
+    define-property "^0.2.5"
+    kind-of "^3.0.3"
 
 object-fit-images@^3.2.3:
-  version "3.2.3"
-  resolved "https://registry.yarnpkg.com/object-fit-images/-/object-fit-images-3.2.3.tgz#4089f6d0070a3b5563d3c1ab6f1b28d61331f0ac"
+  version "3.2.4"
+  resolved "https://registry.yarnpkg.com/object-fit-images/-/object-fit-images-3.2.4.tgz#6c299d38fdf207746e5d2d46c2877f6f25d15b52"
+  integrity sha512-G+7LzpYfTfqUyrZlfrou/PLLLAPNC52FTy5y1CBywX+1/FkxIloOyQXBmZ3Zxa2AWO+lMF0JTuvqbr7G5e5CWg==
+
+object-inspect@^1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
+  integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==
 
 object-is@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6"
+  integrity sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=
 
-object-keys@^1.0.10, object-keys@^1.0.8:
-  version "1.0.11"
-  resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
+object-keys@^1.0.11, object-keys@^1.0.12:
+  version "1.0.12"
+  resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2"
+  integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==
 
-object-path@^0.9.2:
-  version "0.9.2"
-  resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5"
+object-visit@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb"
+  integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=
+  dependencies:
+    isobject "^3.0.0"
 
-object.assign@^4.0.4:
-  version "4.0.4"
-  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc"
+object.assign@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
+  integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
   dependencies:
     define-properties "^1.1.2"
-    function-bind "^1.1.0"
-    object-keys "^1.0.10"
+    function-bind "^1.1.1"
+    has-symbols "^1.0.0"
+    object-keys "^1.0.11"
 
 object.entries@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f"
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519"
+  integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==
+  dependencies:
+    define-properties "^1.1.3"
+    es-abstract "^1.12.0"
+    function-bind "^1.1.1"
+    has "^1.0.3"
+
+object.fromentries@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab"
+  integrity sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==
   dependencies:
     define-properties "^1.1.2"
-    es-abstract "^1.6.1"
-    function-bind "^1.1.0"
+    es-abstract "^1.11.0"
+    function-bind "^1.1.1"
     has "^1.0.1"
 
+object.getownpropertydescriptors@^2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
+  integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=
+  dependencies:
+    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"
+  integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=
+  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=
   dependencies:
     define-properties "^1.1.2"
     es-abstract "^1.6.1"
     function-bind "^1.1.0"
     has "^1.0.1"
 
-obuf@^1.0.0, obuf@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.1.tgz#104124b6c602c6796881a042541d36db43a5264e"
+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@^4.8.3:
-  version "4.8.4"
-  resolved "https://registry.yarnpkg.com/offline-plugin/-/offline-plugin-4.8.4.tgz#1084c59f6606bded5ee5a6bf6208e2b9f5bdd339"
+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==
   dependencies:
-    deep-extend "^0.4.0"
+    deep-extend "^0.5.1"
     ejs "^2.3.4"
     loader-utils "0.2.x"
     minimatch "^3.0.3"
@@ -5041,38 +6433,45 @@ offline-plugin@^4.8.3:
 on-finished@~2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
+  integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
   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=
 
-once@^1.3.0, once@^1.3.3, once@^1.4.0:
+once@^1.3.0, once@^1.3.1, once@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+  integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
   dependencies:
     wrappy "1"
 
 onetime@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
+  integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=
   dependencies:
     mimic-fn "^1.0.0"
 
-opener@^1.4.3:
-  version "1.4.3"
-  resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
+opener@^1.5.1:
+  version "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.1.0"
-  resolved "https://registry.yarnpkg.com/opn/-/opn-5.1.0.tgz#72ce2306a17dbea58ff1041853352b4a8fc77519"
+  version "5.4.0"
+  resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035"
+  integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==
   dependencies:
     is-wsl "^1.1.0"
 
 optimist@^0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
+  integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY=
   dependencies:
     minimist "~0.0.1"
     wordwrap "~0.0.2"
@@ -5080,6 +6479,7 @@ optimist@^0.6.1:
 optionator@^0.8.1, optionator@^0.8.2:
   version "0.8.2"
   resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
+  integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=
   dependencies:
     deep-is "~0.1.3"
     fast-levenshtein "~2.0.4"
@@ -5088,78 +6488,135 @@ optionator@^0.8.1, optionator@^0.8.2:
     type-check "~0.3.2"
     wordwrap "~1.0.0"
 
-original@>=0.0.5:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b"
+original@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
+  integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==
   dependencies:
-    url-parse "1.0.x"
+    url-parse "^1.4.3"
 
 os-browserify@^0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
+  integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
 
-os-homedir@^1.0.0, os-homedir@^1.0.1:
+os-homedir@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
-
-os-locale@^1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
-  dependencies:
-    lcid "^1.0.0"
+  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"
+  integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
+  dependencies:
+    execa "^1.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:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+  integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
 
-osenv@0, osenv@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
+osenv@^0.1.4:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
+  integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
   dependencies:
     os-homedir "^1.0.0"
     os-tmpdir "^1.0.0"
 
-p-cancelable@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
+p-defer@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
+  integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=
 
 p-finally@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+  integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
 
-p-limit@^1.1.0:
+p-is-promise@^1.1.0:
   version "1.1.0"
-  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
+  resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
+  integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=
+
+p-limit@^1.1.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
+  integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==
+  dependencies:
+    p-try "^1.0.0"
+
+p-limit@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68"
+  integrity sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==
+  dependencies:
+    p-try "^2.0.0"
 
 p-locate@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
+  integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
   dependencies:
     p-limit "^1.1.0"
 
+p-locate@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
+  integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
+  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-try@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
+  integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
+
+p-try@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1"
+  integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==
 
 packet-reader@0.3.1:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-0.3.1.tgz#cd62e60af8d7fea8a705ec4ff990871c46871f27"
+  integrity sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc=
 
 pako@~1.0.5:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.7.tgz#2473439021b57f1516c82f58be7275ad8ef1bb27"
+  integrity sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==
+
+parallel-transform@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06"
+  integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=
+  dependencies:
+    cyclist "~0.2.2"
+    inherits "^2.0.3"
+    readable-stream "^2.1.5"
 
 parse-asn1@^5.0.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712"
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8"
+  integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==
   dependencies:
     asn1.js "^4.0.0"
     browserify-aes "^1.0.0"
@@ -5170,6 +6627,7 @@ parse-asn1@^5.0.0:
 parse-css-font@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/parse-css-font/-/parse-css-font-2.0.2.tgz#7b60b060705a25a9b90b7f0ed493e5823248a652"
+  integrity sha1-e2CwYHBaJam5C38O1JPlgjJIplI=
   dependencies:
     css-font-size-keywords "^1.0.0"
     css-font-stretch-keywords "^1.0.1"
@@ -5184,6 +6642,7 @@ parse-css-font@^2.0.2:
 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"
@@ -5193,83 +6652,103 @@ parse-glob@^3.0.4:
 parse-json@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
+  integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=
   dependencies:
     error-ex "^1.2.0"
 
-parse-json@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13"
-  dependencies:
-    error-ex "^1.3.1"
-
 parse-json@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
+  integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
   dependencies:
     error-ex "^1.3.1"
     json-parse-better-errors "^1.0.1"
 
-parse5@^1.5.1:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94"
+parse5@4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
+  integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==
 
 parse5@^3.0.1:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
+  integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==
   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=
+
+pascalcase@^0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
+  integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
 
 path-browserify@0.0.0:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"
+  integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=
 
-path-complete-extname@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/path-complete-extname/-/path-complete-extname-0.1.0.tgz#c454702669f31452f8193aa6168915fa31692f4a"
+path-complete-extname@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/path-complete-extname/-/path-complete-extname-1.0.0.tgz#f889985dc91000c815515c0bfed06c5acda0752b"
+  integrity sha512-CVjiWcMRdGU8ubs08YQVzhutOR5DEfO97ipRIlOGMK5Bek5nQySknBpuxVAVJ36hseTNs+vdIcv57ZrWxH7zvg==
+
+path-dirname@^1.0.0:
+  version "1.0.2"
+  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:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+  integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
 
 path-is-inside@^1.0.1, path-is-inside@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
+  integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
 
-path-key@^2.0.0:
+path-key@^2.0.0, path-key@^2.0.1:
   version "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:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+path-parse@^1.0.5, 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==
 
 path-to-regexp@0.1.7:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
+  integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
 
 path-to-regexp@^1.7.0:
   version "1.7.0"
   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
+  integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=
   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"
@@ -5278,24 +6757,14 @@ path-type@^1.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"
+  integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=
   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"
-  dependencies:
-    pify "^3.0.0"
-
-pause-stream@0.0.11:
-  version "0.0.11"
-  resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
-  dependencies:
-    through "~2.3"
-
 pbkdf2@^3.0.3:
-  version "3.0.14"
-  resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade"
+  version "3.0.17"
+  resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
+  integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==
   dependencies:
     create-hash "^1.1.2"
     create-hmac "^1.1.4"
@@ -5306,22 +6775,27 @@ pbkdf2@^3.0.3:
 performance-now@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
+  integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=
 
 performance-now@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
+  integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
 
 pg-connection-string@0.1.3:
   version "0.1.3"
   resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7"
+  integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=
 
 pg-int8@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
+  integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
 
 pg-pool@1.*:
   version "1.8.0"
   resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-1.8.0.tgz#f7ec73824c37a03f076f51bfdf70e340147c4f37"
+  integrity sha1-9+xzgkw3oD8Hb1G/33DjQBR8Tzc=
   dependencies:
     generic-pool "2.4.3"
     object-assign "4.1.0"
@@ -5329,6 +6803,7 @@ pg-pool@1.*:
 pg-types@1.*:
   version "1.13.0"
   resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.13.0.tgz#75f490b8a8abf75f1386ef5ec4455ecf6b345c63"
+  integrity sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==
   dependencies:
     pg-int8 "1.0.1"
     postgres-array "~1.0.0"
@@ -5339,6 +6814,7 @@ pg-types@1.*:
 pg@^6.4.0:
   version "6.4.2"
   resolved "https://registry.yarnpkg.com/pg/-/pg-6.4.2.tgz#c364011060eac7a507a2ae063eb857ece910e27f"
+  integrity sha1-w2QBEGDqx6UHoq4GPrhX7OkQ4n8=
   dependencies:
     buffer-writer "1.0.1"
     js-string-escape "1.0.1"
@@ -5352,722 +6828,677 @@ pg@^6.4.0:
 pgpass@1.*:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306"
+  integrity sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=
   dependencies:
     split "^1.0.0"
 
-pify@^2.0.0, pify@^2.3.0:
+pify@^2.0.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+  integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
 
 pify@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
+  integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
 
 pinkie-promise@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+  integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
   dependencies:
     pinkie "^2.0.0"
 
 pinkie@^2.0.0:
   version "2.0.4"
   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=
   dependencies:
     find-up "^1.0.0"
 
 pkg-dir@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
+  integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=
   dependencies:
     find-up "^2.1.0"
 
+pkg-dir@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3"
+  integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==
+  dependencies:
+    find-up "^3.0.0"
+
 pluralize@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
+  integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==
 
-portfinder@^1.0.9:
-  version "1.0.13"
-  resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
-  dependencies:
-    async "^1.5.2"
-    debug "^2.2.0"
-    mkdirp "0.5.x"
-
-postcss-advanced-variables@1.2.2:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/postcss-advanced-variables/-/postcss-advanced-variables-1.2.2.tgz#90a6213262e66a050a368b4a9c5d4778d72dbd74"
-  dependencies:
-    postcss "^5.0.10"
-
-postcss-atroot@^0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/postcss-atroot/-/postcss-atroot-0.1.3.tgz#6752c0230c745140549345b2b0e30ebeda01a405"
-  dependencies:
-    postcss "^5.0.5"
-
-postcss-calc@^5.2.0:
-  version "5.3.1"
-  resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e"
-  dependencies:
-    postcss "^5.0.2"
-    postcss-message-helpers "^2.0.0"
-    reduce-css-calc "^1.2.6"
-
-postcss-color-function@^4.0.0:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-color-function/-/postcss-color-function-4.0.1.tgz#402b3f2cebc3f6947e618fb6be3654fbecef6444"
-  dependencies:
-    css-color-function "~1.3.3"
-    postcss "^6.0.1"
-    postcss-message-helpers "^2.0.0"
-    postcss-value-parser "^3.3.0"
-
-postcss-colormin@^2.1.8:
-  version "2.2.2"
-  resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b"
-  dependencies:
-    colormin "^1.0.5"
-    postcss "^5.0.13"
-    postcss-value-parser "^3.2.3"
-
-postcss-convert-values@^2.3.4:
-  version "2.6.1"
-  resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d"
-  dependencies:
-    postcss "^5.0.11"
-    postcss-value-parser "^3.1.2"
-
-postcss-custom-media@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-6.0.0.tgz#be532784110ecb295044fb5395a18006eb21a737"
-  dependencies:
-    postcss "^6.0.1"
-
-postcss-custom-properties@^6.1.0:
-  version "6.2.0"
-  resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-6.2.0.tgz#5d929a7f06e9b84e0f11334194c0ba9a30acfbe9"
-  dependencies:
-    balanced-match "^1.0.0"
-    postcss "^6.0.13"
-
-postcss-custom-selectors@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-4.0.1.tgz#781382f94c52e727ef5ca4776ea2adf49a611382"
-  dependencies:
-    postcss "^6.0.1"
-    postcss-selector-matches "^3.0.0"
-
-postcss-discard-comments@^2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d"
-  dependencies:
-    postcss "^5.0.14"
-
-postcss-discard-duplicates@^2.0.1:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932"
-  dependencies:
-    postcss "^5.0.4"
+pn@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
+  integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
 
-postcss-discard-empty@^2.0.1:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5"
+portfinder@^1.0.9:
+  version "1.0.20"
+  resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a"
+  integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==
   dependencies:
-    postcss "^5.0.14"
+    async "^1.5.2"
+    debug "^2.2.0"
+    mkdirp "0.5.x"
 
-postcss-discard-overridden@^0.1.1:
+posix-character-classes@^0.1.0:
   version "0.1.1"
-  resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58"
-  dependencies:
-    postcss "^5.0.16"
-
-postcss-discard-unused@^2.2.1:
-  version "2.2.3"
-  resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433"
-  dependencies:
-    postcss "^5.0.14"
-    uniqs "^2.0.0"
+  resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
+  integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
 
-postcss-extend@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/postcss-extend/-/postcss-extend-1.0.5.tgz#5ea98bf787ba3cacf4df4609743f80a833b1d0e7"
+postcss-calc@^7.0.0:
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436"
+  integrity sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==
   dependencies:
-    postcss "^5.0.4"
+    css-unit-converter "^1.1.1"
+    postcss "^7.0.5"
+    postcss-selector-parser "^5.0.0-rc.4"
+    postcss-value-parser "^3.3.1"
 
-postcss-filter-plugins@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz#6d85862534d735ac420e4a85806e1f5d4286d84c"
+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==
   dependencies:
-    postcss "^5.0.4"
-    uniqid "^4.0.0"
+    browserslist "^4.0.0"
+    color "^3.0.0"
+    has "^1.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-import@^10.0.0:
-  version "10.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-10.0.0.tgz#4c85c97b099136cc5ea0240dc1dfdbfde4e2ebbe"
+postcss-convert-values@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f"
+  integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==
   dependencies:
-    object-assign "^4.0.1"
-    postcss "^6.0.1"
-    postcss-value-parser "^3.2.3"
-    read-cache "^1.0.0"
-    resolve "^1.1.7"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-js@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-1.0.1.tgz#ffaf29226e399ea74b5dce02cab1729d7addbc7b"
+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==
   dependencies:
-    camelcase-css "^1.0.1"
-    postcss "^6.0.11"
+    postcss "^7.0.0"
 
-postcss-load-config@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-1.2.0.tgz#539e9afc9ddc8620121ebf9d8c3673e0ce50d28a"
+postcss-discard-duplicates@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb"
+  integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==
   dependencies:
-    cosmiconfig "^2.1.0"
-    object-assign "^4.1.0"
-    postcss-load-options "^1.2.0"
-    postcss-load-plugins "^2.3.0"
+    postcss "^7.0.0"
 
-postcss-load-options@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/postcss-load-options/-/postcss-load-options-1.2.0.tgz#b098b1559ddac2df04bc0bb375f99a5cfe2b6d8c"
+postcss-discard-empty@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765"
+  integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==
   dependencies:
-    cosmiconfig "^2.1.0"
-    object-assign "^4.1.0"
+    postcss "^7.0.0"
 
-postcss-load-plugins@^2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz#745768116599aca2f009fad426b00175049d8d92"
+postcss-discard-overridden@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57"
+  integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==
   dependencies:
-    cosmiconfig "^2.1.1"
-    object-assign "^4.1.0"
+    postcss "^7.0.0"
 
-postcss-loader@^2.0.9:
-  version "2.0.9"
-  resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.0.9.tgz#001fdf7bfeeb159405ee61d1bb8e59b528dbd309"
+postcss-load-config@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.0.0.tgz#f1312ddbf5912cd747177083c5ef7a19d62ee484"
+  integrity sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==
   dependencies:
-    loader-utils "^1.1.0"
-    postcss "^6.0.0"
-    postcss-load-config "^1.2.0"
-    schema-utils "^0.3.0"
+    cosmiconfig "^4.0.0"
+    import-cwd "^2.0.0"
 
-postcss-media-minmax@^3.0.0:
+postcss-loader@^3.0.0:
   version "3.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-3.0.0.tgz#675256037a43ef40bc4f0760bfd06d4dc69d48d2"
-  dependencies:
-    postcss "^6.0.1"
-
-postcss-merge-idents@^2.1.5:
-  version "2.1.7"
-  resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270"
+  resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d"
+  integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==
   dependencies:
-    has "^1.0.1"
-    postcss "^5.0.10"
-    postcss-value-parser "^3.1.1"
+    loader-utils "^1.1.0"
+    postcss "^7.0.0"
+    postcss-load-config "^2.0.0"
+    schema-utils "^1.0.0"
 
-postcss-merge-longhand@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658"
+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==
   dependencies:
-    postcss "^5.0.4"
+    css-color-names "0.0.4"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
+    stylehacks "^4.0.0"
 
-postcss-merge-rules@^2.0.3:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721"
-  dependencies:
-    browserslist "^1.5.2"
-    caniuse-api "^1.5.2"
-    postcss "^5.0.4"
-    postcss-selector-parser "^2.2.2"
+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==
+  dependencies:
+    browserslist "^4.0.0"
+    caniuse-api "^3.0.0"
+    cssnano-util-same-parent "^4.0.0"
+    postcss "^7.0.0"
+    postcss-selector-parser "^3.0.0"
     vendors "^1.0.0"
 
-postcss-message-helpers@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e"
-
-postcss-minify-font-values@^1.0.2:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69"
+postcss-minify-font-values@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6"
+  integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==
   dependencies:
-    object-assign "^4.0.1"
-    postcss "^5.0.4"
-    postcss-value-parser "^3.0.2"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-minify-gradients@^1.0.1:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1"
+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==
   dependencies:
-    postcss "^5.0.12"
-    postcss-value-parser "^3.3.0"
+    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@^1.0.4:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3"
-  dependencies:
-    alphanum-sort "^1.0.1"
-    postcss "^5.0.2"
-    postcss-value-parser "^3.0.2"
+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==
+  dependencies:
+    alphanum-sort "^1.0.0"
+    browserslist "^4.0.0"
+    cssnano-util-get-arguments "^4.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
     uniqs "^2.0.0"
 
-postcss-minify-selectors@^2.0.4:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf"
-  dependencies:
-    alphanum-sort "^1.0.2"
-    has "^1.0.1"
-    postcss "^5.0.14"
-    postcss-selector-parser "^2.0.0"
-
-postcss-mixins@^6.0.1:
-  version "6.2.0"
-  resolved "https://registry.yarnpkg.com/postcss-mixins/-/postcss-mixins-6.2.0.tgz#fa9d2c2166b2ae7745956c727ab9dd2de4b96a40"
+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==
   dependencies:
-    globby "^6.1.0"
-    postcss "^6.0.13"
-    postcss-js "^1.0.1"
-    postcss-simple-vars "^4.1.0"
-    sugarss "^1.0.0"
+    alphanum-sort "^1.0.0"
+    has "^1.0.0"
+    postcss "^7.0.0"
+    postcss-selector-parser "^3.0.0"
 
-postcss-modules-extract-imports@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz#b614c9720be6816eaee35fb3a5faa1dba6a05ddb"
+postcss-modules-extract-imports@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e"
+  integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==
   dependencies:
-    postcss "^6.0.1"
+    postcss "^7.0.5"
 
-postcss-modules-local-by-default@^1.0.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069"
+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==
   dependencies:
     css-selector-tokenizer "^0.7.0"
-    postcss "^6.0.1"
+    postcss "^7.0.6"
+    postcss-value-parser "^3.3.1"
 
-postcss-modules-scope@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90"
+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==
   dependencies:
     css-selector-tokenizer "^0.7.0"
-    postcss "^6.0.1"
+    postcss "^7.0.6"
 
-postcss-modules-values@^1.1.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20"
+postcss-modules-values@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64"
+  integrity sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==
   dependencies:
     icss-replace-symbols "^1.1.0"
-    postcss "^6.0.1"
-
-postcss-nested@^2.0.2:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-2.1.2.tgz#04057281f9631fef684857fb0119bae04ede03c6"
-  dependencies:
-    postcss "^6.0.9"
-    postcss-selector-parser "^2.2.3"
-
-postcss-nesting@^4.0.1:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-4.2.1.tgz#0483bce338b3f0828ced90ff530b29b98b00300d"
-  dependencies:
-    postcss "^6.0.11"
+    postcss "^7.0.6"
 
-postcss-normalize-charset@^1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1"
+postcss-normalize-charset@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4"
+  integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==
   dependencies:
-    postcss "^5.0.5"
+    postcss "^7.0.0"
 
-postcss-normalize-url@^3.0.7:
-  version "3.0.8"
-  resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222"
+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==
   dependencies:
-    is-absolute-url "^2.0.0"
-    normalize-url "^1.4.0"
-    postcss "^5.0.14"
-    postcss-value-parser "^3.2.3"
+    cssnano-util-get-match "^4.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-object-fit-images@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/postcss-object-fit-images/-/postcss-object-fit-images-1.1.2.tgz#8b773043db14672ef6cd6f2cb1f0d8b26a9f573b"
+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==
   dependencies:
-    parse-css-font "^2.0.2"
-    postcss "^5.0.16"
-    quote "^0.4.0"
+    cssnano-util-get-arguments "^4.0.0"
+    has "^1.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-ordered-values@^2.1.0:
-  version "2.2.3"
-  resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d"
+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==
   dependencies:
-    postcss "^5.0.4"
-    postcss-value-parser "^3.0.1"
+    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-partial-import@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/postcss-partial-import/-/postcss-partial-import-4.1.0.tgz#f6c3e78e7bbeda4d9dab96d360367b90b353f9a4"
+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==
   dependencies:
-    glob "^7.1.1"
-    postcss-import "^10.0.0"
+    has "^1.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-property-lookup@^1.2.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/postcss-property-lookup/-/postcss-property-lookup-1.2.1.tgz#30450a1361b7aae758bbedd5201fbe057bb8270b"
+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==
   dependencies:
-    object-assign "^4.0.1"
-    postcss "^5.0.4"
-    tcomb "^2.5.1"
+    cssnano-util-get-match "^4.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-reduce-idents@^2.2.2:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3"
+postcss-normalize-unicode@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb"
+  integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==
   dependencies:
-    postcss "^5.0.4"
-    postcss-value-parser "^3.0.2"
+    browserslist "^4.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-reduce-initial@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea"
+postcss-normalize-url@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1"
+  integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==
   dependencies:
-    postcss "^5.0.4"
+    is-absolute-url "^2.0.0"
+    normalize-url "^3.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-reduce-transforms@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1"
+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==
   dependencies:
-    has "^1.0.1"
-    postcss "^5.0.8"
-    postcss-value-parser "^3.0.1"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-sass@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/postcss-sass/-/postcss-sass-0.1.0.tgz#0d2a655b5d241ec8f419bb3da38de5ca11746ddb"
+postcss-object-fit-images@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/postcss-object-fit-images/-/postcss-object-fit-images-1.1.2.tgz#8b773043db14672ef6cd6f2cb1f0d8b26a9f573b"
+  integrity sha1-i3cwQ9sUZy72zW8ssfDYsmqfVzs=
   dependencies:
-    gonzales-pe "^4.0.3"
-    mathjs "^3.11.5"
-    postcss "^5.2.6"
+    parse-css-font "^2.0.2"
+    postcss "^5.0.16"
+    quote "^0.4.0"
 
-postcss-scss@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-1.0.2.tgz#ff45cf3354b879ee89a4eb68680f46ac9bb14f94"
+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==
   dependencies:
-    postcss "^6.0.3"
+    cssnano-util-get-arguments "^4.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-selector-matches@^3.0.0, postcss-selector-matches@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz#e5634011e13950881861bbdd58c2d0111ffc96ab"
+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==
   dependencies:
-    balanced-match "^0.4.2"
-    postcss "^6.0.1"
+    browserslist "^4.0.0"
+    caniuse-api "^3.0.0"
+    has "^1.0.0"
+    postcss "^7.0.0"
 
-postcss-selector-not@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-3.0.1.tgz#2e4db2f0965336c01e7cec7db6c60dff767335d9"
+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==
   dependencies:
-    balanced-match "^0.4.2"
-    postcss "^6.0.1"
+    cssnano-util-get-match "^4.0.0"
+    has "^1.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
 
-postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2, postcss-selector-parser@^2.2.3:
-  version "2.2.3"
-  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90"
+postcss-selector-parser@^3.0.0:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865"
+  integrity sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=
   dependencies:
-    flatten "^1.0.2"
+    dot-prop "^4.1.1"
     indexes-of "^1.0.1"
     uniq "^1.0.1"
 
-postcss-simple-vars@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-4.1.0.tgz#043248cfef8d3f51b3486a28c09f8375dbf1b2f9"
-  dependencies:
-    postcss "^6.0.9"
-
-postcss-smart-import@^0.7.5:
-  version "0.7.5"
-  resolved "https://registry.yarnpkg.com/postcss-smart-import/-/postcss-smart-import-0.7.5.tgz#df9a9c6dd60d916e5e0670d1c57d03af5d3dcc31"
+postcss-selector-parser@^5.0.0-rc.4:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c"
+  integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==
   dependencies:
-    babel-runtime "^6.23.0"
-    lodash "^4.17.4"
-    object-assign "^4.1.1"
-    postcss "^6.0.6"
-    postcss-sass "^0.1.0"
-    postcss-scss "^1.0.2"
-    postcss-value-parser "^3.3.0"
-    promise-each "^2.2.0"
-    read-cache "^1.0.0"
-    resolve "^1.3.3"
-    sugarss "^1.0.0"
+    cssesc "^2.0.0"
+    indexes-of "^1.0.1"
+    uniq "^1.0.1"
 
-postcss-svgo@^2.1.1:
-  version "2.1.6"
-  resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d"
+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==
   dependencies:
-    is-svg "^2.0.0"
-    postcss "^5.0.14"
-    postcss-value-parser "^3.2.3"
-    svgo "^0.7.0"
+    is-svg "^3.0.0"
+    postcss "^7.0.0"
+    postcss-value-parser "^3.0.0"
+    svgo "^1.0.0"
 
-postcss-unique-selectors@^2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d"
+postcss-unique-selectors@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac"
+  integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==
   dependencies:
-    alphanum-sort "^1.0.1"
-    postcss "^5.0.4"
+    alphanum-sort "^1.0.0"
+    postcss "^7.0.0"
     uniqs "^2.0.0"
 
-postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15"
-
-postcss-zindex@^2.0.1:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22"
-  dependencies:
-    has "^1.0.1"
-    postcss "^5.0.4"
-    uniqs "^2.0.0"
+postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1:
+  version "3.3.1"
+  resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
+  integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
 
-postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16, postcss@^5.2.6:
+postcss@^5.0.16:
   version "5.2.18"
   resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5"
+  integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==
   dependencies:
     chalk "^1.1.3"
     js-base64 "^2.1.9"
     source-map "^0.5.6"
     supports-color "^3.2.3"
 
-postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.13, postcss@^6.0.14, postcss@^6.0.3, postcss@^6.0.6, postcss@^6.0.9:
-  version "6.0.14"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885"
+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==
   dependencies:
-    chalk "^2.3.0"
+    chalk "^2.4.1"
     source-map "^0.6.1"
-    supports-color "^4.4.0"
+    supports-color "^5.5.0"
 
 postgres-array@~1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-1.0.2.tgz#8e0b32eb03bf77a5c0a7851e0441c169a256a238"
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-1.0.3.tgz#c561fc3b266b21451fc6555384f4986d78ec80f5"
+  integrity sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==
 
 postgres-bytea@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
+  integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=
 
 postgres-date@~1.0.0:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.3.tgz#e2d89702efdb258ff9d9cee0fe91bd06975257a8"
+  integrity sha1-4tiXAu/bJY/52c7g/pG9BpdSV6g=
 
 postgres-interval@^1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.1.1.tgz#acdb0f897b4b1c6e496d9d4e0a853e1c428f06f0"
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.1.2.tgz#bf71ff902635f21cb241a013fc421d81d1db15a9"
+  integrity sha512-fC3xNHeTskCxL1dC8KOtxXt7YeFmlbTYtn7ul8MkVERuTmf7pI4DrkAxcw3kh1fQ9uz4wQmd03a1mRiXUZChfQ==
   dependencies:
     xtend "^4.0.0"
 
 precond@0.2:
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac"
-
-precss@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/precss/-/precss-2.0.0.tgz#7f567e3318e06d44c8fdbf9e58452e8358bf4b71"
-  dependencies:
-    postcss "^6.0.3"
-    postcss-advanced-variables "1.2.2"
-    postcss-atroot "^0.1.3"
-    postcss-color-function "^4.0.0"
-    postcss-custom-media "^6.0.0"
-    postcss-custom-properties "^6.1.0"
-    postcss-custom-selectors "^4.0.1"
-    postcss-extend "^1.0.5"
-    postcss-media-minmax "^3.0.0"
-    postcss-mixins "^6.0.1"
-    postcss-nested "^2.0.2"
-    postcss-nesting "^4.0.1"
-    postcss-partial-import "^4.1.0"
-    postcss-property-lookup "^1.2.1"
-    postcss-selector-matches "^3.0.1"
-    postcss-selector-not "^3.0.1"
+  integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=
 
 prelude-ls@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
-
-prepend-http@^1.0.0:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
+  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=
 
-pretty-format@^21.2.1:
-  version "21.2.1"
-  resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.2.1.tgz#ae5407f3cf21066cd011aa1ba5fce7b6a2eddb36"
+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==
   dependencies:
     ansi-regex "^3.0.0"
     ansi-styles "^3.2.0"
 
-private@^0.1.6, private@^0.1.7:
+private@^0.1.6, private@^0.1.8:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
+  integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
 
-process-nextick-args@~1.0.6:
-  version "1.0.7"
-  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+process-nextick-args@~2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
+  integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
 
 process@^0.11.10:
   version "0.11.10"
   resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
+  integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
 
 progress@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
+  integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
 
-promise-each@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/promise-each/-/promise-each-2.2.0.tgz#3353174eff2694481037e04e01f77aa0fb6d1b60"
-  dependencies:
-    any-promise "^0.1.0"
+promise-inflight@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
+  integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
 
 promise@^7.1.1:
   version "7.3.1"
   resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+  integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
   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==
+  dependencies:
+    kleur "^2.0.1"
+    sisteransi "^0.1.1"
+
 prop-types-extra@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.0.1.tgz#a57bd4810e82d27a3ff4317ecc1b4ad005f79a82"
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.0.tgz#32609910ea2dcf190366bacd3490d5a6412a605f"
+  integrity sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==
   dependencies:
+    react-is "^16.3.2"
     warning "^3.0.0"
 
-prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0:
-  version "15.6.0"
-  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
+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==
   dependencies:
-    fbjs "^0.8.16"
     loose-envify "^1.3.1"
     object-assign "^4.1.1"
 
-proxy-addr@~2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
+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==
   dependencies:
     forwarded "~0.1.2"
-    ipaddr.js "1.5.2"
+    ipaddr.js "1.8.0"
 
-prr@~0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
-
-ps-tree@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014"
-  dependencies:
-    event-stream "~3.3.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"
+  integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==
 
 public-encrypt@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6"
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
+  integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==
   dependencies:
     bn.js "^4.1.0"
     browserify-rsa "^4.0.0"
     create-hash "^1.1.0"
     parse-asn1 "^5.0.0"
     randombytes "^2.0.1"
+    safe-buffer "^5.1.2"
+
+pump@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
+  integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==
+  dependencies:
+    end-of-stream "^1.1.0"
+    once "^1.3.1"
+
+pump@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
+  integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
+  dependencies:
+    end-of-stream "^1.1.0"
+    once "^1.3.1"
+
+pumpify@^1.3.3:
+  version "1.5.1"
+  resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce"
+  integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==
+  dependencies:
+    duplexify "^3.6.0"
+    inherits "^2.0.3"
+    pump "^2.0.0"
 
 punycode@1.3.2:
   version "1.3.2"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
+  integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
 
 punycode@^1.2.4, punycode@^1.4.1:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+  integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
 
-punycode@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d"
+punycode@^2.1.0, punycode@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
+  integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
 
 q@^1.1.2:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
+  integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
 
-qs@6.5.1, qs@~6.5.1:
-  version "6.5.1"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
-
-qs@~6.3.0:
-  version "6.3.2"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c"
-
-qs@~6.4.0:
-  version "6.4.0"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
-
-query-string@^4.1.0:
-  version "4.3.4"
-  resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb"
-  dependencies:
-    object-assign "^4.1.0"
-    strict-uri-encode "^1.0.0"
+qs@6.5.2, 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==
 
 querystring-es3@^0.2.0:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
+  integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
 
 querystring@0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
+  integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
 
-querystringify@0.0.x:
-  version "0.0.4"
-  resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c"
-
-querystringify@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb"
+querystringify@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef"
+  integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==
 
 quote@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/quote/-/quote-0.4.0.tgz#10839217f6c1362b89194044d29b233fd7f32f01"
+  integrity sha1-EIOSF/bBNiuJGUBE0psjP9fzLwE=
 
-raf@^3.1.0, raf@^3.4.0:
-  version "3.4.0"
-  resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
+raf@^3.1.0, raf@^3.4.0, raf@^3.4.1:
+  version "3.4.1"
+  resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
+  integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
   dependencies:
     performance-now "^2.1.0"
 
 railroad-diagrams@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
+  integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=
 
-rails-ujs@^5.1.2:
-  version "5.1.4"
-  resolved "https://registry.yarnpkg.com/rails-ujs/-/rails-ujs-5.1.4.tgz#e2e9f7bcbfe51ee69c5f72f4beb0d88ab81a638e"
+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==
 
-randexp@^0.4.2:
+randexp@0.4.6:
   version "0.4.6"
   resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
+  integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==
   dependencies:
     discontinuous-range "1.0.0"
     ret "~0.1.10"
 
-randomatic@^1.1.3:
-  version "1.1.7"
-  resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"
+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 "^3.0.0"
-    kind-of "^4.0.0"
+    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.5"
-  resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79"
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"
+  integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==
   dependencies:
     safe-buffer "^5.1.0"
 
 randomfill@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.3.tgz#b96b7df587f01dd91726c418f30553b1418e3d62"
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
+  integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==
   dependencies:
     randombytes "^2.0.5"
     safe-buffer "^5.1.0"
@@ -6075,95 +7506,144 @@ randomfill@^1.0.3:
 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=
 
-raw-body@2.3.2:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
+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==
   dependencies:
     bytes "3.0.0"
-    http-errors "1.6.2"
-    iconv-lite "0.4.19"
+    http-errors "1.6.3"
+    iconv-lite "0.4.23"
     unpipe "1.0.0"
 
-rc@^1.1.7:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
+rc@^1.2.7:
+  version "1.2.8"
+  resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
+  integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
   dependencies:
-    deep-extend "~0.4.0"
+    deep-extend "^0.6.0"
     ini "~1.3.0"
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
 
-react-dom@^16.3.0:
-  version "16.3.2"
-  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.3.2.tgz#cb90f107e09536d683d84ed5d4888e9640e0e4df"
+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==
   dependencies:
-    fbjs "^0.8.16"
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
-    prop-types "^15.6.0"
+    prop-types "^15.6.2"
+    scheduler "^0.12.0"
 
-react-event-listener@^0.5.1:
-  version "0.5.1"
-  resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.5.1.tgz#ba36076e47bc37c5a67ff5ccd4a9ff0f15621040"
+react-event-listener@^0.6.0:
+  version "0.6.5"
+  resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.6.5.tgz#d374dbe5da485c9f9d4702f0e76971afbe9b6b2e"
+  integrity sha512-//lCxOM3DQ0+xmTa/u9mI9mm55zCPdIKp89d8MGjlNsOOnXQ5sFDD1eed+sMBzQXKiRBLBMtSg/2T9RJFtfovw==
   dependencies:
-    babel-runtime "^6.26.0"
-    fbjs "^0.8.16"
+    "@babel/runtime" "7.2.0"
     prop-types "^15.6.0"
-    warning "^3.0.0"
+    warning "^4.0.1"
 
-react-hotkeys@^0.10.0:
-  version "0.10.0"
-  resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-0.10.0.tgz#d1e78bd63f16d6db58d550d33c8eb071f35d94fb"
+react-hotkeys@^1.1.4:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-1.1.4.tgz#a0712aa2e0c03a759fd7885808598497a4dace72"
+  integrity sha1-oHEqouDAOnWf14hYCFmEl6TaznI=
   dependencies:
-    create-react-class "^15.5.2"
-    lodash "^4.13.1"
+    lodash.isboolean "^3.0.3"
+    lodash.isequal "^4.5.0"
+    lodash.isobject "^3.0.2"
     mousetrap "^1.5.2"
-    prop-types "^15.5.8"
+    prop-types "^15.6.0"
 
 react-immutable-proptypes@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#023d6f39bb15c97c071e9e60d00d136eac5fa0b4"
+  integrity sha1-Aj1vObsVyXwHHp5g0A0TbqxfoLQ=
 
 react-immutable-pure-component@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/react-immutable-pure-component/-/react-immutable-pure-component-1.1.1.tgz#0ff69c6d4eaecd886db16805f3bbc1d2a2c654d8"
+  version "1.2.3"
+  resolved "https://registry.yarnpkg.com/react-immutable-pure-component/-/react-immutable-pure-component-1.2.3.tgz#fa33638df68cfe9f73ccbee1d5861c17f3053f86"
+  integrity sha512-kNy2A/fDrSuR8TKwB+4ynmItmp1vgF87tWxxfmadwDYo2J3ANipHqTjDIBvJvJ7libvuh76jIbvmK0krjtKH1g==
+  optionalDependencies:
+    "@types/react" "16.4.6"
 
-react-intl-translations-manager@^5.0.0:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/react-intl-translations-manager/-/react-intl-translations-manager-5.0.1.tgz#f0ef1a9368abcac3b10b2e8b6027887dced5474e"
+react-infinite-scroller@^1.0.12:
+  version "1.2.4"
+  resolved "https://registry.yarnpkg.com/react-infinite-scroller/-/react-infinite-scroller-1.2.4.tgz#f67eaec4940a4ce6417bebdd6e3433bfc38826e9"
+  integrity sha512-/oOa0QhZjXPqaD6sictN2edFMsd3kkMiE19Vcz5JDgHpzEJVqYcmq+V3mkwO88087kvKGe1URNksHEOt839Ubw==
   dependencies:
-    chalk "^2.1.0"
+    prop-types "^15.5.8"
+
+react-input-autosize@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8"
+  integrity sha512-3+K4CD13iE4lQQ2WlF8PuV5htfmTRLH6MDnfndHM6LuBRszuXnuyIfE7nhSKt8AzRBZ50bu0sAhkNMeS5pxQQA==
+  dependencies:
+    prop-types "^15.5.8"
+
+react-intl-translations-manager@^5.0.3:
+  version "5.0.3"
+  resolved "https://registry.yarnpkg.com/react-intl-translations-manager/-/react-intl-translations-manager-5.0.3.tgz#aee010ecf35975673e033ca5d7d3f4147894324d"
+  integrity sha512-EfBeugnOGFcdUbQyY9TqBMbuauQ8wm73ZqFr0UqCljhbXl7YDHQcVzclWFRkVmlUffzxitLQFhAZEVVeRNQSwA==
+  dependencies:
+    chalk "^2.3.2"
     glob "^7.1.2"
     json-stable-stringify "^1.0.1"
     mkdirp "^0.5.1"
 
-react-intl@^2.4.0:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.4.0.tgz#66c14dc9df9a73b2fbbfbd6021726e80a613eb15"
+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==
   dependencies:
+    hoist-non-react-statics "^2.5.5"
     intl-format-cache "^2.0.5"
     intl-messageformat "^2.1.0"
-    intl-relativeformat "^2.0.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-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
+  integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
+
+react-masonry-infinite@^1.2.2:
+  version "1.2.2"
+  resolved "https://registry.yarnpkg.com/react-masonry-infinite/-/react-masonry-infinite-1.2.2.tgz#20c1386f9ccdda9747527c8f42bc2c02dd2e7951"
+  integrity sha1-IME4b5zN2pdHUnyPQrwsAt0ueVE=
+  dependencies:
+    bricks.js "^1.7.0"
+    prop-types "^15.5.10"
+    react-infinite-scroller "^1.0.12"
+
 react-motion@^0.5.2:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316"
+  integrity sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==
   dependencies:
     performance-now "^0.2.0"
     prop-types "^15.5.8"
     raf "^3.1.0"
 
-react-notification@^6.8.2:
-  version "6.8.2"
-  resolved "https://registry.yarnpkg.com/react-notification/-/react-notification-6.8.2.tgz#5d9910cc2993bd51a234d3809e94a98dc490cfb0"
+react-notification@^6.8.4:
+  version "6.8.4"
+  resolved "https://registry.yarnpkg.com/react-notification/-/react-notification-6.8.4.tgz#c189d23f47b0e1b240932f4cfab2f4082cd420bf"
+  integrity sha512-El4aaIYeXNpL2M96t4+qg3ODgvAhvpORRCXhseukYlR0X8Efiak9ixGmxgm/Bm5Z43kRdFzpgHlh0uM242IFxA==
   dependencies:
-    prop-types "^15.5.10"
+    prop-types "^15.6.2"
 
 react-overlays@^0.8.3:
   version "0.8.3"
   resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.8.3.tgz#fad65eea5b24301cca192a169f5dddb0b20d3ac5"
+  integrity sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==
   dependencies:
     classnames "^2.2.5"
     dom-helpers "^3.2.1"
@@ -6172,138 +7652,160 @@ react-overlays@^0.8.3:
     react-transition-group "^2.2.0"
     warning "^3.0.0"
 
-react-redux-loading-bar@^2.9.3:
-  version "2.9.3"
-  resolved "https://registry.yarnpkg.com/react-redux-loading-bar/-/react-redux-loading-bar-2.9.3.tgz#65865dddcbf597169e787edec15eec7ebfb84149"
+react-redux-loading-bar@^4.0.8:
+  version "4.0.8"
+  resolved "https://registry.yarnpkg.com/react-redux-loading-bar/-/react-redux-loading-bar-4.0.8.tgz#e84d59d1517b79f53b0f39c8ddb40682af648c1b"
+  integrity sha512-BpR1tlYrYKFtGhxa7nAKc0dpcV33ZgXJ/jKNLpDDaxu2/cCxbkWQt9YlWT+VLw1x/7qyNYY4DH48bZdtmciSpg==
   dependencies:
-    prop-types "^15.5.6"
+    prop-types "^15.6.2"
+    react-lifecycles-compat "^3.0.2"
 
-react-redux@^5.0.4:
-  version "5.0.6"
-  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946"
+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==
   dependencies:
-    hoist-non-react-statics "^2.2.1"
-    invariant "^2.0.0"
-    lodash "^4.2.0"
-    lodash-es "^4.2.0"
-    loose-envify "^1.1.0"
-    prop-types "^15.5.10"
+    "@babel/runtime" "^7.2.0"
+    hoist-non-react-statics "^3.2.1"
+    invariant "^2.2.4"
+    loose-envify "^1.4.0"
+    prop-types "^15.6.2"
+    react-is "^16.6.3"
 
 react-router-dom@^4.1.1:
-  version "4.2.2"
-  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.2.2.tgz#c8a81df3adc58bba8a76782e946cbd4eae649b8d"
+  version "4.3.1"
+  resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6"
+  integrity sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==
   dependencies:
     history "^4.7.2"
-    invariant "^2.2.2"
+    invariant "^2.2.4"
     loose-envify "^1.3.1"
-    prop-types "^15.5.4"
-    react-router "^4.2.0"
-    warning "^3.0.0"
+    prop-types "^15.6.1"
+    react-router "^4.3.1"
+    warning "^4.0.1"
 
 react-router-scroll-4@^1.0.0-beta.1:
-  version "1.0.0-beta.1"
-  resolved "https://registry.yarnpkg.com/react-router-scroll-4/-/react-router-scroll-4-1.0.0-beta.1.tgz#b1838c6e67b9fe64db33176958e88836e10bc4ce"
+  version "1.0.0-beta.2"
+  resolved "https://registry.yarnpkg.com/react-router-scroll-4/-/react-router-scroll-4-1.0.0-beta.2.tgz#d887063ec0f66124aaf450158dd158ff7d3dc279"
+  integrity sha512-K67Dnm75naSBs/WYc2CDNxqU+eE8iA3I0wSCArgGSHb0xR/7AUcgUEXtCxrQYVTogXvjVK60gmwYvOyRQ6fuBA==
   dependencies:
-    babel-eslint "^8.0.1"
     scroll-behavior "^0.9.1"
     warning "^3.0.0"
 
-react-router@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.2.0.tgz#61f7b3e3770daeb24062dae3eedef1b054155986"
+react-router@^4.3.1:
+  version "4.3.1"
+  resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e"
+  integrity sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==
   dependencies:
     history "^4.7.2"
-    hoist-non-react-statics "^2.3.0"
-    invariant "^2.2.2"
+    hoist-non-react-statics "^2.5.0"
+    invariant "^2.2.4"
     loose-envify "^1.3.1"
     path-to-regexp "^1.7.0"
-    prop-types "^15.5.4"
-    warning "^3.0.0"
+    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==
+  dependencies:
+    classnames "^2.2.5"
+    create-emotion "^10.0.4"
+    memoize-one "^4.0.0"
+    prop-types "^15.6.0"
+    raf "^3.4.0"
+    react-input-autosize "^2.2.1"
+    react-transition-group "^2.2.1"
 
 react-sparklines@^1.7.0:
   version "1.7.0"
   resolved "https://registry.yarnpkg.com/react-sparklines/-/react-sparklines-1.7.0.tgz#9b1d97e8c8610095eeb2ad658d2e1fcf91f91a60"
+  integrity sha512-bJFt9K4c5Z0k44G8KtxIhbG+iyxrKjBZhdW6afP+R7EnIq+iKjbWbEFISrf3WKNFsda+C46XAfnX0StS5fbDcg==
   dependencies:
     prop-types "^15.5.10"
 
-react-swipeable-views-core@^0.12.11:
-  version "0.12.11"
-  resolved "https://registry.yarnpkg.com/react-swipeable-views-core/-/react-swipeable-views-core-0.12.11.tgz#3cf2b4daffbb36f9d69bd19bf5b2d5370b6b2c1b"
+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==
   dependencies:
-    babel-runtime "^6.23.0"
-    warning "^3.0.0"
+    "@babel/runtime" "7.0.0"
+    warning "^4.0.1"
 
-react-swipeable-views-utils@^0.12.11:
-  version "0.12.11"
-  resolved "https://registry.yarnpkg.com/react-swipeable-views-utils/-/react-swipeable-views-utils-0.12.11.tgz#3c9a6a2b8dbdcc331a5d107419578f57b7e101d6"
+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==
   dependencies:
-    babel-runtime "^6.23.0"
+    "@babel/runtime" "7.0.0"
     fbjs "^0.8.4"
     keycode "^2.1.7"
     prop-types "^15.6.0"
-    react-event-listener "^0.5.1"
-    react-swipeable-views-core "^0.12.11"
+    react-event-listener "^0.6.0"
+    react-swipeable-views-core "^0.13.0"
 
-react-swipeable-views@^0.12.3:
-  version "0.12.12"
-  resolved "https://registry.yarnpkg.com/react-swipeable-views/-/react-swipeable-views-0.12.12.tgz#60cdc8e3682ed082aaf094f7761eaf691ed28a6f"
+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==
   dependencies:
-    babel-runtime "^6.23.0"
+    "@babel/runtime" "7.0.0"
     dom-helpers "^3.2.1"
     prop-types "^15.5.4"
-    react-swipeable-views-core "^0.12.11"
-    react-swipeable-views-utils "^0.12.11"
-    warning "^3.0.0"
+    react-swipeable-views-core "^0.13.0"
+    react-swipeable-views-utils "^0.13.0"
+    warning "^4.0.1"
 
-react-test-renderer@^16.0.0-0, react-test-renderer@^16.2.0:
-  version "16.2.0"
-  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.2.0.tgz#bddf259a6b8fcd8555f012afc8eacc238872a211"
+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==
   dependencies:
-    fbjs "^0.8.16"
     object-assign "^4.1.1"
-    prop-types "^15.6.0"
+    prop-types "^15.6.2"
+    react-is "^16.7.0"
+    scheduler "^0.12.0"
 
-react-textarea-autosize@^5.2.1:
-  version "5.2.1"
-  resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-5.2.1.tgz#2b78f9067180f41b08ac59f78f1581abadd61e54"
+react-textarea-autosize@^7.1.0:
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.0.tgz#3132cb77e65d94417558d37c0bfe415a5afd3445"
+  integrity sha512-c2FlR/fP0qbxmlrW96SdrbgP/v0XZMTupqB90zybvmDVDutytUgPl7beU35klwcTeMepUIQEpQUn3P3bdshGPg==
   dependencies:
+    "@babel/runtime" "^7.1.2"
     prop-types "^15.6.0"
 
 react-toggle@^4.0.1:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/react-toggle/-/react-toggle-4.0.2.tgz#77f487860efb87fafd197672a2db8c885be1440f"
+  integrity sha512-EPTWnN7gQHgEAUEmjheanZXNzY5TPnQeyyHfEs3YshaiWZf5WNjfYDrglO5F1Hl/dNveX18i4l0grTEsYH2Ccw==
   dependencies:
     classnames "^2.2.5"
 
-react-transition-group@^2.2.0:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10"
+react-transition-group@^2.2.0, react-transition-group@^2.2.1:
+  version "2.5.2"
+  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.5.2.tgz#9457166a9ba6ce697a3e1b076b3c049b9fb2c408"
+  integrity sha512-vwHP++S+f6KL7rg8V1mfs62+MBKtbMeZDR8KiNmD7v98Gs3UPGsDZDahPJH2PVprFW5YHJfh6cbNim3zPndaSQ==
   dependencies:
-    chain-function "^1.0.0"
-    classnames "^2.2.5"
-    dom-helpers "^3.2.0"
-    loose-envify "^1.3.1"
-    prop-types "^15.5.8"
-    warning "^3.0.0"
+    dom-helpers "^3.3.1"
+    loose-envify "^1.4.0"
+    prop-types "^15.6.2"
+    react-lifecycles-compat "^3.0.4"
 
-react@^16.3.0:
-  version "16.3.2"
-  resolved "https://registry.yarnpkg.com/react/-/react-16.3.2.tgz#fdc8420398533a1e58872f59091b272ce2f91ea9"
+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==
   dependencies:
-    fbjs "^0.8.16"
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
-    prop-types "^15.6.0"
-
-read-cache@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
-  dependencies:
-    pify "^2.3.0"
+    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"
@@ -6311,6 +7813,7 @@ read-pkg-up@^1.0.1:
 read-pkg-up@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
+  integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=
   dependencies:
     find-up "^2.0.0"
     read-pkg "^2.0.0"
@@ -6318,6 +7821,7 @@ read-pkg-up@^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=
   dependencies:
     load-json-file "^1.0.0"
     normalize-package-data "^2.3.2"
@@ -6326,335 +7830,336 @@ read-pkg@^1.0.0:
 read-pkg@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
+  integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=
   dependencies:
     load-json-file "^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"
-  dependencies:
-    load-json-file "^4.0.0"
-    normalize-package-data "^2.3.2"
-    path-type "^3.0.0"
-
-readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3:
-  version "2.3.3"
-  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
+"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"
+  integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
   dependencies:
     core-util-is "~1.0.0"
     inherits "~2.0.3"
     isarray "~1.0.0"
-    process-nextick-args "~1.0.6"
+    process-nextick-args "~2.0.0"
     safe-buffer "~5.1.1"
-    string_decoder "~1.0.3"
+    string_decoder "~1.1.1"
     util-deprecate "~1.0.1"
 
+readable-stream@^3.0.6:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06"
+  integrity sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==
+  dependencies:
+    inherits "^2.0.3"
+    string_decoder "^1.1.1"
+    util-deprecate "^1.0.1"
+
 readdirp@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
+  integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==
   dependencies:
-    graceful-fs "^4.1.2"
-    minimatch "^3.0.2"
+    graceful-fs "^4.1.11"
+    micromatch "^3.1.10"
     readable-stream "^2.0.2"
-    set-immediate-shim "^1.0.1"
 
-redent@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
+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==
   dependencies:
-    indent-string "^2.1.0"
-    strip-indent "^1.0.1"
+    util.promisify "^1.0.0"
 
 redis-commands@^1.2.0:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.1.tgz#81d826f45fa9c8b2011f4cd7a0fe597d241d442b"
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.4.0.tgz#52f9cf99153efcce56a8f86af986bd04e988602f"
+  integrity sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==
 
 redis-parser@^2.6.0:
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b"
+  integrity sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=
 
 redis@^2.7.1:
   version "2.8.0"
   resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02"
+  integrity sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==
   dependencies:
     double-ended-queue "^2.1.0-0"
     redis-commands "^1.2.0"
     redis-parser "^2.6.0"
 
-reduce-css-calc@^1.2.6:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716"
-  dependencies:
-    balanced-match "^0.4.2"
-    math-expression-evaluator "^1.2.14"
-    reduce-function-call "^1.0.1"
-
-reduce-function-call@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99"
-  dependencies:
-    balanced-match "^0.4.2"
-
 redux-immutable@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/redux-immutable/-/redux-immutable-4.0.0.tgz#3a1a32df66366462b63691f0e1dc35e472bbc9f3"
+  integrity sha1-Ohoy32Y2ZGK2NpHw4dw15HK7yfM=
 
 redux-thunk@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5"
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
+  integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==
 
-redux@^3.7.1:
-  version "3.7.2"
-  resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b"
+redux@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5"
+  integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==
   dependencies:
-    lodash "^4.2.1"
-    lodash-es "^4.2.1"
-    loose-envify "^1.1.0"
-    symbol-observable "^1.0.3"
+    loose-envify "^1.4.0"
+    symbol-observable "^1.2.0"
 
-regenerate@^1.2.1:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f"
+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==
+  dependencies:
+    regenerate "^1.4.0"
+
+regenerate@^1.2.1, regenerate@^1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
+  integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
 
 regenerator-runtime@^0.11.0:
-  version "0.11.0"
-  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1"
+  version "0.11.1"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
+  integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
 
-regenerator-transform@^0.10.0:
-  version "0.10.1"
-  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"
+regenerator-runtime@^0.12.0:
+  version "0.12.1"
+  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:
-    babel-runtime "^6.18.0"
-    babel-types "^6.19.0"
     private "^0.1.6"
 
 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==
   dependencies:
     is-equal-shallow "^0.1.3"
 
-regex-parser@^2.2.1:
-  version "2.2.8"
-  resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.8.tgz#da4c0cda5a828559094168930f455f532b6ffbac"
+regex-not@^1.0.0, regex-not@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
+  integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==
+  dependencies:
+    extend-shallow "^3.0.2"
+    safe-regex "^1.1.0"
 
-regexpp@^1.0.1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab"
+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@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240"
+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==
   dependencies:
-    regenerate "^1.2.1"
-    regjsgen "^0.2.0"
-    regjsparser "^0.1.4"
+    regenerate "^1.4.0"
+    regenerate-unicode-properties "^7.0.0"
+    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=
+
+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"
+  integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==
   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==
+
 remove-trailing-separator@^1.0.1:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
+  integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
 
 repeat-element@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
+  version "1.1.3"
+  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.5.2, 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@2, request@^2.79.0:
-  version "2.83.0"
-  resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
+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"
+  integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=
+  dependencies:
+    lodash "^4.13.1"
+
+request-promise-native@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5"
+  integrity sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=
+  dependencies:
+    request-promise-core "1.1.1"
+    stealthy-require "^1.1.0"
+    tough-cookie ">=2.3.3"
+
+request@^2.87.0:
+  version "2.88.0"
+  resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
+  integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
   dependencies:
     aws-sign2 "~0.7.0"
-    aws4 "^1.6.0"
+    aws4 "^1.8.0"
     caseless "~0.12.0"
-    combined-stream "~1.0.5"
-    extend "~3.0.1"
+    combined-stream "~1.0.6"
+    extend "~3.0.2"
     forever-agent "~0.6.1"
-    form-data "~2.3.1"
-    har-validator "~5.0.3"
-    hawk "~6.0.2"
+    form-data "~2.3.2"
+    har-validator "~5.1.0"
     http-signature "~1.2.0"
     is-typedarray "~1.0.0"
     isstream "~0.1.2"
     json-stringify-safe "~5.0.1"
-    mime-types "~2.1.17"
-    oauth-sign "~0.8.2"
+    mime-types "~2.1.19"
+    oauth-sign "~0.9.0"
     performance-now "^2.1.0"
-    qs "~6.5.1"
-    safe-buffer "^5.1.1"
-    stringstream "~0.0.5"
-    tough-cookie "~2.3.3"
-    tunnel-agent "^0.6.0"
-    uuid "^3.1.0"
-
-request@2.81.0:
-  version "2.81.0"
-  resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
-  dependencies:
-    aws-sign2 "~0.6.0"
-    aws4 "^1.2.1"
-    caseless "~0.12.0"
-    combined-stream "~1.0.5"
-    extend "~3.0.0"
-    forever-agent "~0.6.1"
-    form-data "~2.1.1"
-    har-validator "~4.2.1"
-    hawk "~3.1.3"
-    http-signature "~1.1.0"
-    is-typedarray "~1.0.0"
-    isstream "~0.1.2"
-    json-stringify-safe "~5.0.1"
-    mime-types "~2.1.7"
-    oauth-sign "~0.8.1"
-    performance-now "^0.2.0"
-    qs "~6.4.0"
-    safe-buffer "^5.0.1"
-    stringstream "~0.0.4"
-    tough-cookie "~2.3.0"
+    qs "~6.5.2"
+    safe-buffer "^5.1.2"
+    tough-cookie "~2.4.3"
     tunnel-agent "^0.6.0"
-    uuid "^3.0.0"
-
-request@~2.79.0:
-  version "2.79.0"
-  resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
-  dependencies:
-    aws-sign2 "~0.6.0"
-    aws4 "^1.2.1"
-    caseless "~0.11.0"
-    combined-stream "~1.0.5"
-    extend "~3.0.0"
-    forever-agent "~0.6.1"
-    form-data "~2.1.1"
-    har-validator "~2.0.6"
-    hawk "~3.1.3"
-    http-signature "~1.1.0"
-    is-typedarray "~1.0.0"
-    isstream "~0.1.2"
-    json-stringify-safe "~5.0.1"
-    mime-types "~2.1.7"
-    oauth-sign "~0.8.1"
-    qs "~6.3.0"
-    stringstream "~0.0.4"
-    tough-cookie "~2.3.0"
-    tunnel-agent "~0.4.1"
-    uuid "^3.0.0"
+    uuid "^3.3.2"
 
 requestidlecallback@^0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/requestidlecallback/-/requestidlecallback-0.3.0.tgz#6fb74e0733f90df3faa4838f9f6a2a5f9b742ac5"
+  integrity sha1-b7dOBzP5DfP6pIOPn2oqX5t0KsU=
 
 require-directory@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+  integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
 
-require-from-string@^1.1.0:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418"
-
-require-from-string@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff"
+require-from-string@^2.0.1, require-from-string@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
+  integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
 
 require-main-filename@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
+  integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=
 
 require-package-name@^2.0.1:
   version "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:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
+  integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=
   dependencies:
     caller-path "^0.1.0"
     resolve-from "^1.0.0"
 
-requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0:
+requires-port@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+  integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
 
-reselect@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147"
+reselect@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7"
+  integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==
 
 resolve-cwd@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
+  integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=
   dependencies:
     resolve-from "^3.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"
+  integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=
 
 resolve-from@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
+  integrity sha1-six699nWiBvItuZTM17rywoYh0g=
 
 resolve-pathname@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
+  integrity sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==
 
-resolve-url-loader@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-2.2.0.tgz#9662feaa11debf7cf8e3feb91dae9544aa7dee88"
-  dependencies:
-    adjust-sourcemap-loader "^1.1.0"
-    camelcase "^4.0.0"
-    convert-source-map "^1.1.1"
-    loader-utils "^1.0.0"
-    lodash.defaults "^4.0.0"
-    rework "^1.0.1"
-    rework-visit "^1.0.0"
-    source-map "^0.5.6"
-    urix "^0.1.0"
-
-resolve-url@~0.2.1:
+resolve-url@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
+  integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
 
 resolve@1.1.7:
   version "1.1.7"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
+  integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
 
-resolve@^1.1.7, resolve@^1.3.3, resolve@^1.5.0:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
+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==
   dependencies:
-    path-parse "^1.0.5"
+    path-parse "^1.0.6"
 
 restore-cursor@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
+  integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368=
   dependencies:
     onetime "^2.0.0"
     signal-exit "^3.0.2"
@@ -6662,159 +8167,188 @@ restore-cursor@^2.0.0:
 ret@~0.1.10:
   version "0.1.15"
   resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
+  integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
 
-rework-visit@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a"
-
-rework@^1.0.1:
+rgb-regex@^1.0.1:
   version "1.0.1"
-  resolved "https://registry.yarnpkg.com/rework/-/rework-1.0.1.tgz#30806a841342b54510aa4110850cd48534144aa7"
-  dependencies:
-    convert-source-map "^0.3.3"
-    css "^2.0.0"
-
-rgb@~0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/rgb/-/rgb-0.1.0.tgz#be27b291e8feffeac1bd99729721bfa40fc037b5"
+  resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1"
+  integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE=
 
-right-align@^0.1.1:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
-  dependencies:
-    align-text "^0.1.1"
+rgba-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
+  integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
 
-rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1:
+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==
   dependencies:
     glob "^7.0.5"
 
 ripemd160@^2.0.0, ripemd160@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7"
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
+  integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
   dependencies:
-    hash-base "^2.0.0"
+    hash-base "^3.0.0"
     inherits "^2.0.1"
 
 rst-selector-parser@^2.2.3:
   version "2.2.3"
   resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91"
+  integrity sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=
   dependencies:
     lodash.flattendeep "^4.4.0"
     nearley "^2.7.10"
 
+rsvp@^3.3.3:
+  version "3.6.2"
+  resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
+  integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==
+
 run-async@^2.2.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
+  integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA=
   dependencies:
     is-promise "^2.1.0"
 
-rx-lite-aggregates@^4.0.8:
-  version "4.0.8"
-  resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
+run-queue@^1.0.0, run-queue@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
+  integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=
   dependencies:
-    rx-lite "*"
+    aproba "^1.1.1"
 
-rx-lite@*, rx-lite@^4.0.8:
-  version "4.0.8"
-  resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
+rxjs@^6.1.0:
+  version "6.3.3"
+  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
+  integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==
+  dependencies:
+    tslib "^1.9.0"
 
-safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
+safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+  version "5.1.2"
+  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
+  integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+
+safe-regex@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e"
+  integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4=
+  dependencies:
+    ret "~0.1.10"
+
+"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
+  integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
 
 sane@^2.0.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/sane/-/sane-2.2.0.tgz#d6d2e2fcab00e3d283c93b912b7c3a20846f1d56"
+  version "2.5.2"
+  resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa"
+  integrity sha1-tNwYYcIbQn6SlQej51HiosuKs/o=
   dependencies:
-    anymatch "^1.3.0"
+    anymatch "^2.0.0"
+    capture-exit "^1.2.0"
     exec-sh "^0.2.0"
     fb-watchman "^2.0.0"
-    minimatch "^3.0.2"
+    micromatch "^3.1.4"
     minimist "^1.1.1"
     walker "~1.0.5"
     watch "~0.18.0"
   optionalDependencies:
-    fsevents "^1.1.1"
-
-sass-graph@^2.2.4:
-  version "2.2.4"
-  resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49"
-  dependencies:
-    glob "^7.0.0"
-    lodash "^4.0.0"
-    scss-tokenizer "^0.2.3"
-    yargs "^7.0.0"
+    fsevents "^1.2.3"
 
-sass-loader@^6.0.6:
-  version "6.0.6"
-  resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-6.0.6.tgz#e9d5e6c1f155faa32a4b26d7a9b7107c225e40f9"
+sass-loader@^7.0.3:
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.1.0.tgz#16fd5138cb8b424bf8a759528a1972d72aad069d"
+  integrity sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==
   dependencies:
-    async "^2.1.5"
-    clone-deep "^0.3.0"
+    clone-deep "^2.0.1"
     loader-utils "^1.0.1"
     lodash.tail "^4.1.1"
+    neo-async "^2.5.0"
     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==
+  dependencies:
+    chokidar "^2.0.0"
 
-sax@^1.2.1, sax@~1.2.1:
+sax@^1.2.4, sax@~1.2.4:
   version "1.2.4"
   resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
+  integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
 
-schema-utils@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf"
+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==
   dependencies:
-    ajv "^5.0.0"
+    loose-envify "^1.1.0"
+    object-assign "^4.1.1"
 
-scroll-behavior@^0.9.1:
-  version "0.9.5"
-  resolved "https://registry.yarnpkg.com/scroll-behavior/-/scroll-behavior-0.9.5.tgz#41da30b559da004eb48450f6cff6068c7696ff23"
+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:
-    dom-helpers "^3.2.1"
-    invariant "^2.2.2"
+    ajv "^6.1.0"
+    ajv-keywords "^3.1.0"
 
-scss-tokenizer@^0.2.3:
-  version "0.2.3"
-  resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
+schema-utils@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
+  integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==
   dependencies:
-    js-base64 "^2.1.8"
-    source-map "^0.4.2"
+    ajv "^6.1.0"
+    ajv-errors "^1.0.0"
+    ajv-keywords "^3.1.0"
 
-seed-random@2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54"
+scroll-behavior@^0.9.1:
+  version "0.9.9"
+  resolved "https://registry.yarnpkg.com/scroll-behavior/-/scroll-behavior-0.9.9.tgz#ebfe0658455b82ad885b66195215416674dacce2"
+  integrity sha1-6/4GWEVbgq2IW2YZUhVBZnTazOI=
+  dependencies:
+    dom-helpers "^3.2.1"
+    invariant "^2.2.2"
 
 select-hose@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
+  integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
 
 selfsigned@^1.9.1:
-  version "1.10.1"
-  resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.1.tgz#bf8cb7b83256c4551e31347c6311778db99eec52"
+  version "1.10.4"
+  resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd"
+  integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==
   dependencies:
-    node-forge "0.6.33"
+    node-forge "0.7.5"
 
-"semver@2 || 3 || 4 || 5", semver@^5.3.0:
-  version "5.4.1"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
+"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@4.3.2:
   version "4.3.2"
   resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7"
+  integrity sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=
 
-semver@~5.3.0:
-  version "5.3.0"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
-
-send@0.16.1:
-  version "0.16.1"
-  resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3"
+send@0.16.2:
+  version "0.16.2"
+  resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1"
+  integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==
   dependencies:
     debug "2.6.9"
-    depd "~1.1.1"
+    depd "~1.1.2"
     destroy "~1.0.4"
-    encodeurl "~1.0.1"
+    encodeurl "~1.0.2"
     escape-html "~1.0.3"
     etag "~1.8.1"
     fresh "0.5.2"
@@ -6823,11 +8357,17 @@ send@0.16.1:
     ms "2.0.0"
     on-finished "~2.3.0"
     range-parser "~1.2.0"
-    statuses "~1.3.1"
+    statuses "~1.4.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:
   version "1.9.1"
   resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
+  integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=
   dependencies:
     accepts "~1.3.4"
     batch "0.6.1"
@@ -6837,451 +8377,596 @@ serve-index@^1.7.2:
     mime-types "~2.1.17"
     parseurl "~1.3.2"
 
-serve-static@1.13.1:
-  version "1.13.1"
-  resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719"
+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==
   dependencies:
-    encodeurl "~1.0.1"
+    encodeurl "~1.0.2"
     escape-html "~1.0.3"
     parseurl "~1.3.2"
-    send "0.16.1"
+    send "0.16.2"
 
 set-blocking@^2.0.0, set-blocking@~2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+  integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
 
-set-immediate-shim@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
+set-value@^0.4.3:
+  version "0.4.3"
+  resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1"
+  integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE=
+  dependencies:
+    extend-shallow "^2.0.1"
+    is-extendable "^0.1.1"
+    is-plain-object "^2.0.1"
+    to-object-path "^0.3.0"
+
+set-value@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274"
+  integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==
+  dependencies:
+    extend-shallow "^2.0.1"
+    is-extendable "^0.1.1"
+    is-plain-object "^2.0.3"
+    split-string "^3.0.1"
 
 setimmediate@^1.0.4, setimmediate@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
-
-setprototypeof@1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
+  integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
 
 setprototypeof@1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
+  integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
 
 sha.js@^2.4.0, sha.js@^2.4.8:
-  version "2.4.9"
-  resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"
+  version "2.4.11"
+  resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
+  integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
   dependencies:
     inherits "^2.0.1"
     safe-buffer "^5.0.1"
 
-shallow-clone@^0.1.2:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060"
+shallow-clone@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-1.0.0.tgz#4480cd06e882ef68b2ad88a3ea54832e2c48b571"
+  integrity sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==
   dependencies:
     is-extendable "^0.1.1"
-    kind-of "^2.0.1"
-    lazy-cache "^0.2.3"
+    kind-of "^5.0.0"
     mixin-object "^2.0.1"
 
 shebang-command@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
+  integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
   dependencies:
     shebang-regex "^1.0.0"
 
 shebang-regex@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+  integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
 
-shell-quote@^1.6.1:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
-  dependencies:
-    array-filter "~0.0.0"
-    array-map "~0.0.0"
-    array-reduce "~0.0.0"
-    jsonify "~0.0.0"
-
-shellwords@^0.1.0:
+shellwords@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
+  integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
 
 signal-exit@^3.0.0, signal-exit@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
+  integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
+
+simple-swizzle@^0.2.2:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
+  integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=
+  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==
 
 slash@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
+  integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
 
-slice-ansi@1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
+slice-ansi@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7"
+  integrity sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==
   dependencies:
+    ansi-styles "^3.2.0"
+    astral-regex "^1.0.0"
     is-fullwidth-code-point "^2.0.0"
 
-sntp@1.x.x:
-  version "1.0.9"
-  resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+snapdragon-node@^2.0.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
+  integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==
   dependencies:
-    hoek "2.x.x"
+    define-property "^1.0.0"
+    isobject "^3.0.0"
+    snapdragon-util "^3.0.1"
 
-sntp@2.x.x:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
+snapdragon-util@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2"
+  integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==
   dependencies:
-    hoek "4.x.x"
+    kind-of "^3.2.0"
 
-sockjs-client@1.1.4:
-  version "1.1.4"
-  resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12"
+snapdragon@^0.8.1:
+  version "0.8.2"
+  resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d"
+  integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==
   dependencies:
-    debug "^2.6.6"
-    eventsource "0.1.6"
-    faye-websocket "~0.11.0"
-    inherits "^2.0.1"
-    json3 "^3.3.2"
-    url-parse "^1.1.8"
+    base "^0.11.1"
+    debug "^2.2.0"
+    define-property "^0.2.5"
+    extend-shallow "^2.0.1"
+    map-cache "^0.2.2"
+    source-map "^0.5.6"
+    source-map-resolve "^0.5.0"
+    use "^3.1.0"
 
-sockjs@0.3.18:
-  version "0.3.18"
-  resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.18.tgz#d9b289316ca7df77595ef299e075f0f937eb4207"
+sockjs-client@1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177"
+  integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==
   dependencies:
-    faye-websocket "^0.10.0"
-    uuid "^2.0.2"
+    debug "^3.2.5"
+    eventsource "^1.0.7"
+    faye-websocket "~0.11.1"
+    inherits "^2.0.3"
+    json3 "^3.3.2"
+    url-parse "^1.4.3"
 
-sort-keys@^1.0.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
+sockjs@0.3.19:
+  version "0.3.19"
+  resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d"
+  integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==
   dependencies:
-    is-plain-obj "^1.0.0"
+    faye-websocket "^0.10.0"
+    uuid "^3.0.1"
 
 source-list-map@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
+  integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
 
-source-map-resolve@^0.3.0:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761"
+source-map-resolve@^0.5.0:
+  version "0.5.2"
+  resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259"
+  integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==
   dependencies:
-    atob "~1.1.0"
-    resolve-url "~0.2.1"
-    source-map-url "~0.3.0"
-    urix "~0.1.0"
+    atob "^2.1.1"
+    decode-uri-component "^0.2.0"
+    resolve-url "^0.2.1"
+    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-url@~0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9"
-
-source-map@^0.1.38:
-  version "0.1.43"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
+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==
   dependencies:
-    amdefine ">=0.0.4"
+    buffer-from "^1.0.0"
+    source-map "^0.6.0"
 
-source-map@^0.4.2, source-map@^0.4.4:
-  version "0.4.4"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
-  dependencies:
-    amdefine ">=0.0.4"
+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"
+  integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
 
-source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.6:
+source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7:
   version "0.5.7"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+  integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
 
-source-map@^0.6.1, source-map@~0.6.1:
+source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+  integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
 
-spdx-correct@~1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
+spdx-correct@^3.0.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4"
+  integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==
   dependencies:
-    spdx-license-ids "^1.0.2"
+    spdx-expression-parse "^3.0.0"
+    spdx-license-ids "^3.0.0"
 
-spdx-expression-parse@~1.0.0:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
+spdx-exceptions@^2.1.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977"
+  integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==
 
-spdx-license-ids@^1.0.2:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+spdx-expression-parse@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0"
+  integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==
+  dependencies:
+    spdx-exceptions "^2.1.0"
+    spdx-license-ids "^3.0.0"
+
+spdx-license-ids@^3.0.0:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e"
+  integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==
 
-spdy-transport@^2.0.18:
-  version "2.0.20"
-  resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.0.20.tgz#735e72054c486b2354fe89e702256004a39ace4d"
+spdy-transport@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31"
+  integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==
   dependencies:
-    debug "^2.6.8"
-    detect-node "^2.0.3"
+    debug "^4.1.0"
+    detect-node "^2.0.4"
     hpack.js "^2.1.6"
-    obuf "^1.1.1"
-    readable-stream "^2.2.9"
-    safe-buffer "^5.0.1"
-    wbuf "^1.7.2"
+    obuf "^1.1.2"
+    readable-stream "^3.0.6"
+    wbuf "^1.7.3"
 
-spdy@^3.4.1:
-  version "3.4.7"
-  resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc"
+spdy@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.0.tgz#81f222b5a743a329aa12cea6a390e60e9b613c52"
+  integrity sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==
   dependencies:
-    debug "^2.6.8"
-    handle-thing "^1.2.5"
+    debug "^4.1.0"
+    handle-thing "^2.0.0"
     http-deceiver "^1.2.7"
-    safe-buffer "^5.0.1"
     select-hose "^2.0.0"
-    spdy-transport "^2.0.18"
+    spdy-transport "^3.0.0"
 
-split@0.3:
-  version "0.3.3"
-  resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
+split-string@^3.0.1, split-string@^3.0.2:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
+  integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==
   dependencies:
-    through "2"
+    extend-shallow "^3.0.0"
 
 split@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
+  integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==
   dependencies:
     through "2"
 
 sprintf-js@~1.0.2:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+  integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
 
 sshpk@^1.7.0:
-  version "1.13.1"
-  resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
+  version "1.16.0"
+  resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de"
+  integrity sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==
   dependencies:
     asn1 "~0.2.3"
     assert-plus "^1.0.0"
-    dashdash "^1.12.0"
-    getpass "^0.1.1"
-  optionalDependencies:
     bcrypt-pbkdf "^1.0.0"
+    dashdash "^1.12.0"
     ecc-jsbn "~0.1.1"
+    getpass "^0.1.1"
     jsbn "~0.1.0"
+    safer-buffer "^2.0.2"
     tweetnacl "~0.14.0"
 
-"statuses@>= 1.3.1 < 2":
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
+ssri@^6.0.1:
+  version "6.0.1"
+  resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8"
+  integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==
+  dependencies:
+    figgy-pudding "^3.5.1"
 
-statuses@~1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
+stable@~0.1.6:
+  version "0.1.8"
+  resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
+  integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
 
-stdout-stream@^1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b"
+stack-utils@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8"
+  integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==
+
+static-extend@^0.1.1:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
+  integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=
   dependencies:
-    readable-stream "^2.0.1"
+    define-property "^0.2.5"
+    object-copy "^0.1.0"
+
+"statuses@>= 1.4.0 < 2":
+  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"
+  integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
 
 stream-browserify@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"
+  integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=
   dependencies:
     inherits "~2.0.1"
     readable-stream "^2.0.2"
 
-stream-combiner@~0.0.4:
-  version "0.0.4"
-  resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
+stream-each@^1.1.0:
+  version "1.2.3"
+  resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae"
+  integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==
   dependencies:
-    duplexer "~0.1.1"
+    end-of-stream "^1.1.0"
+    stream-shift "^1.0.0"
 
 stream-http@^2.7.2:
-  version "2.7.2"
-  resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad"
+  version "2.8.3"
+  resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc"
+  integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==
   dependencies:
     builtin-status-codes "^3.0.0"
     inherits "^2.0.1"
-    readable-stream "^2.2.6"
+    readable-stream "^2.3.6"
     to-arraybuffer "^1.0.0"
     xtend "^4.0.0"
 
-strict-uri-encode@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
+stream-shift@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
+  integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=
 
 string-length@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed"
+  integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=
   dependencies:
     astral-regex "^1.0.0"
     strip-ansi "^4.0.0"
 
-string-width@^1.0.1, string-width@^1.0.2:
+string-width@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+  integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
   dependencies:
     code-point-at "^1.0.0"
     is-fullwidth-code-point "^1.0.0"
     strip-ansi "^3.0.0"
 
-string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
+"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
+  integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
   dependencies:
     is-fullwidth-code-point "^2.0.0"
     strip-ansi "^4.0.0"
 
-string.prototype.padend@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0"
+string.prototype.trim@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
+  integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=
   dependencies:
     define-properties "^1.1.2"
-    es-abstract "^1.4.3"
+    es-abstract "^1.5.0"
     function-bind "^1.0.2"
 
-string_decoder@^1.0.0, string_decoder@~1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
+string_decoder@^1.0.0, string_decoder@^1.1.1:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
+  integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
+  dependencies:
+    safe-buffer "~5.1.0"
+
+string_decoder@~1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
+  integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
   dependencies:
     safe-buffer "~5.1.0"
 
-stringstream@~0.0.4, stringstream@~0.0.5:
-  version "0.0.5"
-  resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
-
-stringz@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/stringz/-/stringz-0.3.0.tgz#58a311a8c791eee1a68f5f188b3db5e66ff49360"
+stringz@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/stringz/-/stringz-1.0.0.tgz#d2acba994e4ce3c725ee15c86fff4281280d2025"
+  integrity sha512-oaqFaIAmw1MJmdPNiBqocHHrC0VzJTL3CI1z5uXm3NQSE3AyDU152ZPTSJSOKk+9z1Cm3LZzgLFjCTb8SXZvag==
+  dependencies:
+    unicode-astral-regex "^1.0.1"
 
 strip-ansi@^3.0.0, strip-ansi@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+  integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
   dependencies:
     ansi-regex "^2.0.0"
 
 strip-ansi@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
+  integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
   dependencies:
     ansi-regex "^3.0.0"
 
+strip-ansi@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f"
+  integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==
+  dependencies:
+    ansi-regex "^4.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"
+  integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
 
-strip-indent@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
-  dependencies:
-    get-stdin "^4.0.1"
-
-strip-json-comments@~2.0.1:
+strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
   version "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.19.0:
-  version "0.19.0"
-  resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.19.0.tgz#7258e788f0fee6a42d710eaf7d6c2412a4c50759"
+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.0.2"
-    schema-utils "^0.3.0"
+    loader-utils "^1.1.0"
+    schema-utils "^1.0.0"
+
+stylehacks@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.1.tgz#3186595d047ab0df813d213e51c8b94e0b9010f2"
+  integrity sha512-TK5zEPeD9NyC1uPIdjikzsgWxdQQN/ry1X3d1iOz1UkYDCmcr928gWD1KHgyC27F50UnE0xCTrBOO1l6KR8M4w==
+  dependencies:
+    browserslist "^4.0.0"
+    postcss "^7.0.0"
+    postcss-selector-parser "^3.0.0"
 
 substring-trie@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/substring-trie/-/substring-trie-1.0.2.tgz#7b42592391628b4f2cb17365c6cce4257c7b7af5"
-
-sugarss@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-1.0.1.tgz#be826d9003e0f247735f92365dc3fd7f1bae9e44"
-  dependencies:
-    postcss "^6.0.14"
+  integrity sha1-e0JZI5Fii08ssXNlxszkJXx7evU=
 
 supports-color@^2.0.0:
   version "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:
   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@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0:
-  version "4.5.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
+supports-color@^5.1.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 "^2.0.0"
+    has-flag "^3.0.0"
 
-svgo@^0.7.0:
-  version "0.7.2"
-  resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5"
+svgo@^1.0.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.1.1.tgz#12384b03335bcecd85cfa5f4e3375fed671cb985"
+  integrity sha512-GBkJbnTuFpM4jFbiERHDWhZc/S/kpHToqmZag3aEBjPYK44JAN2QBjvrGIxLOoCyMZjuFQIfTO2eJd8uwLY/9g==
   dependencies:
-    coa "~1.0.1"
+    coa "~2.0.1"
     colors "~1.1.2"
-    csso "~2.3.1"
-    js-yaml "~3.7.0"
+    css-select "^2.0.0"
+    css-select-base-adapter "~0.1.0"
+    css-tree "1.0.0-alpha.28"
+    css-url-regex "^1.1.0"
+    csso "^3.5.0"
+    js-yaml "^3.12.0"
     mkdirp "~0.5.1"
-    sax "~1.2.1"
-    whet.extend "~0.9.9"
+    object.values "^1.0.4"
+    sax "~1.2.4"
+    stable "~0.1.6"
+    unquote "~1.1.1"
+    util.promisify "~1.0.0"
 
-symbol-observable@^1.0.3:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
+symbol-observable@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
+  integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
 
-symbol-tree@^3.2.1:
+symbol-tree@^3.2.2:
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
+  integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=
 
-table@4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
+table@^5.0.2:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837"
+  integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw==
   dependencies:
-    ajv "^5.2.3"
-    ajv-keywords "^2.1.0"
-    chalk "^2.1.0"
-    lodash "^4.17.4"
-    slice-ansi "1.0.0"
+    ajv "^6.6.1"
+    lodash "^4.17.11"
+    slice-ansi "2.0.0"
     string-width "^2.1.1"
 
-tapable@^0.2.7:
-  version "0.2.8"
-  resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
-
-tar-pack@^3.4.0:
-  version "3.4.1"
-  resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f"
-  dependencies:
-    debug "^2.2.0"
-    fstream "^1.0.10"
-    fstream-ignore "^1.0.5"
-    once "^1.3.3"
-    readable-stream "^2.1.4"
-    rimraf "^2.5.1"
-    tar "^2.2.1"
-    uid-number "^0.0.6"
-
-tar@^2.0.0, tar@^2.2.1:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
-  dependencies:
-    block-stream "*"
-    fstream "^1.0.2"
-    inherits "2"
+tapable@^1.0.0, tapable@^1.1.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e"
+  integrity sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==
+
+tar@^4:
+  version "4.4.8"
+  resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d"
+  integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==
+  dependencies:
+    chownr "^1.1.1"
+    fs-minipass "^1.2.5"
+    minipass "^2.3.4"
+    minizlib "^1.1.1"
+    mkdirp "^0.5.0"
+    safe-buffer "^5.1.2"
+    yallist "^3.0.2"
 
-tcomb@^2.5.0, tcomb@^2.5.1:
+tcomb@^2.5.0:
   version "2.7.0"
   resolved "https://registry.yarnpkg.com/tcomb/-/tcomb-2.7.0.tgz#10d62958041669a5d53567b9a4ee8cde22b1c2b0"
+  integrity sha1-ENYpWAQWaaXVNWe5pO6M3iKxwrA=
 
-test-exclude@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26"
+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==
+  dependencies:
+    cacache "^11.0.2"
+    find-cache-dir "^2.0.0"
+    schema-utils "^1.0.0"
+    serialize-javascript "^1.4.0"
+    source-map "^0.6.1"
+    terser "^3.8.1"
+    webpack-sources "^1.1.0"
+    worker-farm "^1.5.2"
+
+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==
+  dependencies:
+    commander "~2.17.1"
+    source-map "~0.6.1"
+    source-map-support "~0.5.6"
+
+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==
   dependencies:
     arrify "^1.0.1"
     micromatch "^2.3.11"
@@ -7289,269 +8974,404 @@ test-exclude@^4.1.1:
     read-pkg-up "^1.0.1"
     require-main-filename "^1.0.1"
 
-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=
 
 throat@^4.0.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
+  integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=
 
 throng@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/throng/-/throng-4.0.0.tgz#983c6ba1993b58eae859998aa687ffe88df84c17"
+  integrity sha1-mDxroZk7WOroWZmKpof/6I34TBc=
   dependencies:
     lodash.defaults "^4.0.1"
 
-through@2, through@^2.3.6, through@~2.3, through@~2.3.1:
+through2@^2.0.0:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
+  integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
+  dependencies:
+    readable-stream "~2.3.6"
+    xtend "~4.0.1"
+
+through@2, through@^2.3.6:
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+  integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
 
-thunky@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/thunky/-/thunky-0.1.0.tgz#bf30146824e2b6e67b0f2d7a4ac8beb26908684e"
-
-time-stamp@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357"
+thunky@^1.0.2:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826"
+  integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==
 
 timers-browserify@^2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6"
+  version "2.0.10"
+  resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae"
+  integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==
   dependencies:
     setimmediate "^1.0.4"
 
-tiny-emitter@2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.0.tgz#bad327adb1804b42a231afa741532bd884cd09ad"
+timsort@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
+  integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
 
 tiny-queue@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/tiny-queue/-/tiny-queue-0.2.1.tgz#25a67f2c6e253b2ca941977b5ef7442ef97a6046"
+  integrity sha1-JaZ/LG4lOyypQZd7XvdELvl6YEY=
 
 tmp@^0.0.33:
   version "0.0.33"
   resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
+  integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
   dependencies:
     os-tmpdir "~1.0.2"
 
 tmpl@1.0.x:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
+  integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=
 
 to-arraybuffer@^1.0.0:
   version "1.0.1"
   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"
+  integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
 
-tough-cookie@^2.3.2, tough-cookie@~2.3.0, tough-cookie@~2.3.3:
-  version "2.3.3"
-  resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
+to-object-path@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
+  integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=
+  dependencies:
+    kind-of "^3.0.2"
+
+to-regex-range@^2.1.0:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
+  integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=
+  dependencies:
+    is-number "^3.0.0"
+    repeat-string "^1.6.1"
+
+to-regex@^3.0.1, to-regex@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
+  integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==
+  dependencies:
+    define-property "^2.0.2"
+    extend-shallow "^3.0.2"
+    regex-not "^1.0.2"
+    safe-regex "^1.1.0"
+
+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"
+  integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
   dependencies:
+    psl "^1.1.28"
+    punycode "^2.1.1"
+
+tough-cookie@~2.4.3:
+  version "2.4.3"
+  resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
+  integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
+  dependencies:
+    psl "^1.1.24"
     punycode "^1.4.1"
 
 tr46@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
+  integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=
   dependencies:
     punycode "^2.1.0"
 
-tr46@~0.0.3:
-  version "0.0.3"
-  resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
-
-trim-newlines@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
-
 trim-right@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
+  integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
 
-"true-case-path@^1.0.2":
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62"
-  dependencies:
-    glob "^6.0.4"
+tryer@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
+  integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
+
+tslib@^1.9.0:
+  version "1.9.3"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
+  integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
 
 tty-browserify@0.0.0:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
+  integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
 
 tunnel-agent@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+  integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
   dependencies:
     safe-buffer "^5.0.1"
 
-tunnel-agent@~0.4.1:
-  version "0.4.3"
-  resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
-
 tweetnacl@^0.14.3, tweetnacl@~0.14.0:
   version "0.14.5"
   resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+  integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
 
 type-check@~0.3.2:
   version "0.3.2"
   resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
+  integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
   dependencies:
     prelude-ls "~1.1.2"
 
-type-is@~1.6.15:
-  version "1.6.15"
-  resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"
+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==
   dependencies:
     media-typer "0.3.0"
-    mime-types "~2.1.15"
-
-typed-function@0.10.6:
-  version "0.10.6"
-  resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-0.10.6.tgz#314aa0ea72bd586de5920095559683e20b01688b"
+    mime-types "~2.1.18"
 
 typedarray@^0.0.6:
   version "0.0.6"
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+  integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
-ua-parser-js@^0.7.9:
-  version "0.7.17"
-  resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
+ua-parser-js@^0.7.18:
+  version "0.7.19"
+  resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b"
+  integrity sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==
 
-uglify-js@^2.6, uglify-js@^2.8.29:
-  version "2.8.29"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
+uglify-js@^3.0.0, 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==
   dependencies:
-    source-map "~0.5.1"
-    yargs "~3.10.0"
-  optionalDependencies:
-    uglify-to-browserify "~1.0.0"
+    commander "~2.17.1"
+    source-map "~0.6.1"
 
-uglify-to-browserify@~1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
+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"
 
-uglifyjs-webpack-plugin@^0.4.6:
-  version "0.4.6"
-  resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309"
+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"
+  integrity sha512-UP6cmDeiWi8bMDmkyXLRsDuVPTvPjh8Wsz+pHu1VkGgTBl4pUceYAdHXY0cdc6Q3+Z2q7QMzi/0E7L/S/yOvFw==
+
+unicode-canonical-property-names-ecmascript@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
+  integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==
+
+unicode-match-property-ecmascript@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c"
+  integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==
   dependencies:
-    source-map "^0.5.6"
-    uglify-js "^2.8.29"
-    webpack-sources "^1.0.1"
+    unicode-canonical-property-names-ecmascript "^1.0.4"
+    unicode-property-aliases-ecmascript "^1.0.4"
 
-uid-number@^0.0.6:
-  version "0.0.6"
-  resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
+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==
 
-ultron@~1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
+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==
 
-underscore@~1.4.4:
-  version "1.4.4"
-  resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
+union-value@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"
+  integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=
+  dependencies:
+    arr-union "^3.1.0"
+    get-value "^2.0.6"
+    is-extendable "^0.1.1"
+    set-value "^0.4.3"
 
 uniq@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
-
-uniqid@^4.0.0:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-4.1.1.tgz#89220ddf6b751ae52b5f72484863528596bb84c1"
-  dependencies:
-    macaddress "^0.2.8"
+  integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=
 
 uniqs@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02"
+  integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI=
+
+unique-filename@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230"
+  integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==
+  dependencies:
+    unique-slug "^2.0.0"
+
+unique-slug@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6"
+  integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==
+  dependencies:
+    imurmurhash "^0.1.4"
 
 unpipe@1.0.0, unpipe@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
+  integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
+
+unquote@^1.1.0, unquote@~1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544"
+  integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=
 
-unquote@^1.1.0:
+unset-value@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"
+  integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=
+  dependencies:
+    has-value "^0.3.1"
+    isobject "^3.0.0"
+
+upath@^1.0.5:
   version "1.1.0"
-  resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.0.tgz#98e1fc608b6b854c75afb1b95afc099ba69d942f"
+  resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
+  integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==
+
+uri-js@^4.2.2:
+  version "4.2.2"
+  resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
+  integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
+  dependencies:
+    punycode "^2.1.0"
 
-urix@^0.1.0, urix@~0.1.0:
+urix@^0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
+  integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
 
-url-parse@1.0.x:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b"
-  dependencies:
-    querystringify "0.0.x"
-    requires-port "1.0.x"
-
-url-parse@^1.1.8:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986"
+url-parse@^1.4.3:
+  version "1.4.4"
+  resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8"
+  integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==
   dependencies:
-    querystringify "~1.0.0"
-    requires-port "~1.0.0"
+    querystringify "^2.0.0"
+    requires-port "^1.0.0"
 
 url@^0.11.0:
   version "0.11.0"
   resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
+  integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
   dependencies:
     punycode "1.3.2"
     querystring "0.2.0"
 
-util-deprecate@~1.0.1:
+use@^3.1.0:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
+  integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
+
+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"
+  integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+
+util.promisify@^1.0.0, util.promisify@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030"
+  integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==
+  dependencies:
+    define-properties "^1.1.2"
+    object.getownpropertydescriptors "^2.0.3"
 
-util@0.10.3, util@^0.10.3:
+util@0.10.3:
   version "0.10.3"
   resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
+  integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
   dependencies:
     inherits "2.0.1"
 
+util@^0.10.3:
+  version "0.10.4"
+  resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901"
+  integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==
+  dependencies:
+    inherits "2.0.3"
+
 utils-merge@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
+  integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
 
-uuid@^2.0.2:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
+uuid@^3.0.1, uuid@^3.1.0, uuid@^3.3.2:
+  version "3.3.2"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
+  integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
 
-uuid@^3.0.0, uuid@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
+uws@10.148.0:
+  version "10.148.0"
+  resolved "https://registry.yarnpkg.com/uws/-/uws-10.148.0.tgz#3fcd35f083ca515e091cd33b2d78f0f51a666215"
+  integrity sha512-aJpFgMMyxubiE/ll4nj9nWoQbv0HzZZDWXfwyu78nuFObX0Zoyv3TWjkqKPQ1vb2sMPZoz67tri7QNE6dybNmQ==
 
-uws@^8.14.0:
-  version "8.14.1"
-  resolved "https://registry.yarnpkg.com/uws/-/uws-8.14.1.tgz#de09619f305f6174d5516a9c6942cb120904b20b"
+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"
+  integrity sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==
 
 validate-npm-package-license@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
+  integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
   dependencies:
-    spdx-correct "~1.0.0"
-    spdx-expression-parse "~1.0.0"
+    spdx-correct "^3.0.0"
+    spdx-expression-parse "^3.0.0"
 
 value-equal@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7"
+  integrity sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==
 
 vary@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
+  integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
 
 vendors@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22"
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.2.tgz#7fcb5eef9f5623b156bcea89ec37d63676f21801"
+  integrity sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==
 
 verror@1.10.0:
   version "1.10.0"
   resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
+  integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
   dependencies:
     assert-plus "^1.0.0"
     core-util-is "1.0.2"
@@ -7560,158 +9380,217 @@ verror@1.10.0:
 vm-browserify@0.0.4:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
+  integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=
   dependencies:
     indexof "0.0.1"
 
+w3c-hr-time@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
+  integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=
+  dependencies:
+    browser-process-hrtime "^0.1.2"
+
 walker@~1.0.5:
   version "1.0.7"
   resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
+  integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=
   dependencies:
     makeerror "1.0.x"
 
 warning@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
+  integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=
+  dependencies:
+    loose-envify "^1.0.0"
+
+warning@^4.0.1:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.2.tgz#aa6876480872116fa3e11d434b0d0d8d91e44607"
+  integrity sha512-wbTp09q/9C+jJn4KKJfJfoS6VleK/Dti0yqWSm6KMvJ4MRCXFQNapHuJXutJIrWV0Cf4AhTdeIe4qdKHR1+Hug==
   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.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"
+watchpack@^1.5.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00"
+  integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==
   dependencies:
-    async "^2.1.2"
-    chokidar "^1.7.0"
+    chokidar "^2.0.2"
     graceful-fs "^4.1.2"
+    neo-async "^2.5.0"
 
-wbuf@^1.1.0, wbuf@^1.7.2:
-  version "1.7.2"
-  resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.2.tgz#d697b99f1f59512df2751be42769c1580b5801fe"
+wbuf@^1.1.0, wbuf@^1.7.3:
+  version "1.7.3"
+  resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df"
+  integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==
   dependencies:
     minimalistic-assert "^1.0.0"
 
-webidl-conversions@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
-
-webidl-conversions@^4.0.0, webidl-conversions@^4.0.2:
+webidl-conversions@^4.0.2:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
+  integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
 
-webpack-bundle-analyzer@^2.9.1:
-  version "2.9.1"
-  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.9.1.tgz#c2c8e03e8e5768ed288b39ae9e27a8b8d7b9d476"
-  dependencies:
-    acorn "^5.1.1"
-    chalk "^1.1.3"
-    commander "^2.9.0"
-    ejs "^2.5.6"
-    express "^4.15.2"
-    filesize "^3.5.9"
-    gzip-size "^3.0.0"
-    lodash "^4.17.4"
+webpack-assets-manifest@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/webpack-assets-manifest/-/webpack-assets-manifest-3.1.1.tgz#39bbc3bf2ee57fcd8ba07cda51c9ba4a3c6ae1de"
+  integrity sha512-JV9V2QKc5wEWQptdIjvXDUL1ucbPLH2f27toAY3SNdGZp+xSaStAgpoMcvMZmqtFrBc9a5pTS1058vxyMPOzRQ==
+  dependencies:
+    chalk "^2.0"
+    lodash.get "^4.0"
+    lodash.has "^4.0"
+    mkdirp "^0.5"
+    schema-utils "^1.0.0"
+    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==
+  dependencies:
+    acorn "^5.7.3"
+    bfj "^6.1.1"
+    chalk "^2.4.1"
+    commander "^2.18.0"
+    ejs "^2.6.1"
+    express "^4.16.3"
+    filesize "^3.6.1"
+    gzip-size "^5.0.0"
+    lodash "^4.17.10"
     mkdirp "^0.5.1"
-    opener "^1.4.3"
-    ws "^3.3.1"
+    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==
+  dependencies:
+    chalk "^2.4.1"
+    cross-spawn "^6.0.5"
+    enhanced-resolve "^4.1.0"
+    global-modules-path "^2.3.0"
+    import-local "^2.0.0"
+    interpret "^1.1.0"
+    loader-utils "^1.1.0"
+    supports-color "^5.5.0"
+    v8-compile-cache "^2.0.2"
+    yargs "^12.0.2"
 
-webpack-dev-middleware@^1.11.0:
-  version "1.12.2"
-  resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e"
+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==
   dependencies:
     memory-fs "~0.4.1"
-    mime "^1.5.0"
-    path-is-absolute "^1.0.0"
+    mime "^2.3.1"
     range-parser "^1.0.3"
-    time-stamp "^2.0.0"
+    webpack-log "^2.0.0"
 
-webpack-dev-server@^2.9.5:
-  version "2.9.5"
-  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.5.tgz#79336fba0087a66ae491f4869f6545775b18daa8"
+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==
   dependencies:
     ansi-html "0.0.7"
-    array-includes "^3.0.3"
     bonjour "^3.5.0"
-    chokidar "^1.6.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.17.4"
-    import-local "^0.1.1"
-    internal-ip "1.2.0"
+    http-proxy-middleware "~0.18.0"
+    import-local "^2.0.0"
+    internal-ip "^3.0.1"
     ip "^1.1.5"
     killable "^1.0.0"
     loglevel "^1.4.1"
     opn "^5.1.0"
     portfinder "^1.0.9"
+    schema-utils "^1.0.0"
     selfsigned "^1.9.1"
+    semver "^5.6.0"
     serve-index "^1.7.2"
-    sockjs "0.3.18"
-    sockjs-client "1.1.4"
-    spdy "^3.4.1"
-    strip-ansi "^3.0.1"
-    supports-color "^4.2.1"
-    webpack-dev-middleware "^1.11.0"
-    yargs "^6.6.0"
+    sockjs "0.3.19"
+    sockjs-client "1.3.0"
+    spdy "^4.0.0"
+    strip-ansi "^3.0.0"
+    supports-color "^5.1.0"
+    url "^0.11.0"
+    webpack-dev-middleware "3.4.0"
+    webpack-log "^2.0.0"
+    yargs "12.0.2"
 
-webpack-manifest-plugin@^1.2.1:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-1.3.2.tgz#5ea8ee5756359ddc1d98814324fe43496349a7d4"
+webpack-log@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f"
+  integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==
   dependencies:
-    fs-extra "^0.30.0"
-    lodash ">=3.5 <5"
+    ansi-colors "^3.0.0"
+    uuid "^3.3.2"
 
-webpack-merge@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.1.tgz#f1197a0a973e69c6fbeeb6d658219aa8c0c13555"
+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==
   dependencies:
-    lodash "^4.17.4"
+    lodash "^4.17.5"
 
-webpack-sources@^1.0.1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"
+webpack-sources@^1.0.0, webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85"
+  integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==
   dependencies:
     source-list-map "^2.0.0"
     source-map "~0.6.1"
 
-webpack@^3.9.1:
-  version "3.9.1"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.9.1.tgz#9a60aa544ed5d4d454c069e3f521aa007e02643c"
-  dependencies:
-    acorn "^5.0.0"
-    acorn-dynamic-import "^2.0.0"
-    ajv "^5.1.5"
-    ajv-keywords "^2.0.0"
-    async "^2.1.2"
-    enhanced-resolve "^3.4.0"
-    escope "^3.6.0"
-    interpret "^1.0.0"
-    json-loader "^0.5.4"
-    json5 "^0.5.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"
+    ajv "^6.1.0"
+    ajv-keywords "^3.1.0"
+    chrome-trace-event "^1.0.0"
+    enhanced-resolve "^4.1.0"
+    eslint-scope "^4.0.0"
+    json-parse-better-errors "^1.0.2"
     loader-runner "^2.3.0"
     loader-utils "^1.1.0"
     memory-fs "~0.4.1"
+    micromatch "^3.1.8"
     mkdirp "~0.5.0"
+    neo-async "^2.5.0"
     node-libs-browser "^2.0.0"
-    source-map "^0.5.3"
-    supports-color "^4.2.1"
-    tapable "^0.2.7"
-    uglifyjs-webpack-plugin "^0.4.6"
-    watchpack "^1.4.0"
-    webpack-sources "^1.0.1"
-    yargs "^8.0.2"
+    schema-utils "^0.4.4"
+    tapable "^1.1.0"
+    terser-webpack-plugin "^1.1.0"
+    watchpack "^1.5.0"
+    webpack-sources "^1.3.0"
 
 websocket-driver@>=0.5.1:
   version "0.7.0"
   resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb"
+  integrity sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=
   dependencies:
     http-parser-js ">=0.4.0"
     websocket-extensions ">=0.1.1"
@@ -7719,88 +9598,90 @@ websocket-driver@>=0.5.1:
 websocket-extensions@>=0.1.1:
   version "0.1.3"
   resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
+  integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
 
 websocket.js@^0.1.12:
   version "0.1.12"
   resolved "https://registry.yarnpkg.com/websocket.js/-/websocket.js-0.1.12.tgz#46c980787c57ebc8edcf44a0263e5d639367b85b"
+  integrity sha1-RsmAeHxX68jtz0SgJj5dY5NnuFs=
   dependencies:
     backoff "^2.4.1"
 
-whatwg-encoding@^1.0.1:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3"
+whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
+  integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
   dependencies:
-    iconv-lite "0.4.19"
+    iconv-lite "0.4.24"
 
 whatwg-fetch@>=0.10.0:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
+  integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
 
-whatwg-url@^4.3.0:
-  version "4.8.0"
-  resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0"
-  dependencies:
-    tr46 "~0.0.3"
-    webidl-conversions "^3.0.0"
+whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
+  integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
 
 whatwg-url@^6.4.1:
-  version "6.4.1"
-  resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.1.tgz#fdb94b440fd4ad836202c16e9737d511f012fd67"
+  version "6.5.0"
+  resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8"
+  integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==
   dependencies:
     lodash.sortby "^4.7.0"
     tr46 "^1.0.1"
     webidl-conversions "^4.0.2"
 
-whet.extend@~0.9.9:
-  version "0.9.9"
-  resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"
-
-which-module@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
+whatwg-url@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd"
+  integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==
+  dependencies:
+    lodash.sortby "^4.7.0"
+    tr46 "^1.0.1"
+    webidl-conversions "^4.0.2"
 
 which-module@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
+  integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
 
-which@1, which@^1.2.12, which@^1.2.9:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
+which@^1.2.12, 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==
   dependencies:
     isexe "^2.0.0"
 
 wide-align@^1.1.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710"
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
+  integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
   dependencies:
-    string-width "^1.0.2"
-
-window-size@0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
-
-wordwrap@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
+    string-width "^1.0.2 || 2"
 
 wordwrap@~0.0.2:
   version "0.0.3"
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
+  integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=
 
 wordwrap@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+  integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
 
-worker-farm@^1.3.1:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.2.tgz#32b312e5dc3d5d45d79ef44acc2587491cd729ae"
+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==
   dependencies:
-    errno "^0.1.4"
-    xtend "^4.0.1"
+    errno "~0.1.7"
 
 wrap-ansi@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
+  integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=
   dependencies:
     string-width "^1.0.1"
     strip-ansi "^3.0.1"
@@ -7808,10 +9689,12 @@ wrap-ansi@^2.0.0:
 wrappy@1:
   version "1.0.2"
   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==
   dependencies:
     graceful-fs "^4.1.11"
     imurmurhash "^0.1.4"
@@ -7820,108 +9703,146 @@ write-file-atomic@^2.1.0:
 write@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
+  integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=
   dependencies:
     mkdirp "^0.5.1"
 
-ws@^3.3.1:
-  version "3.3.2"
-  resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.2.tgz#96c1d08b3fefda1d5c1e33700d3bfaa9be2d5608"
+ws@^5.2.0:
+  version "5.2.2"
+  resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f"
+  integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==
   dependencies:
     async-limiter "~1.0.0"
-    safe-buffer "~5.1.0"
-    ultron "~1.1.0"
 
-xml-name-validator@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
+ws@^6.0.0:
+  version "6.1.2"
+  resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8"
+  integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==
+  dependencies:
+    async-limiter "~1.0.0"
+
+xml-name-validator@^3.0.0:
+  version "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:
+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=
 
-yargs-parser@^4.2.0:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c"
+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 "^3.0.0"
+    camelcase "^4.1.0"
 
-yargs-parser@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
+yargs-parser@^11.1.1:
+  version "11.1.1"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
+  integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==
   dependencies:
-    camelcase "^3.0.0"
+    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@^6.6.0:
-  version "6.6.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208"
+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 "^3.0.0"
-    cliui "^3.2.0"
-    decamelize "^1.1.1"
+    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 "^1.4.0"
-    read-pkg-up "^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 "^1.0.2"
-    which-module "^1.0.0"
-    y18n "^3.2.1"
-    yargs-parser "^4.2.0"
+    string-width "^2.0.0"
+    which-module "^2.0.0"
+    y18n "^3.2.1 || ^4.0.0"
+    yargs-parser "^10.1.0"
 
-yargs@^7.0.0:
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"
+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:
-    camelcase "^3.0.0"
-    cliui "^3.2.0"
+    cliui "^4.0.0"
     decamelize "^1.1.1"
+    find-up "^2.1.0"
     get-caller-file "^1.0.1"
-    os-locale "^1.4.0"
-    read-pkg-up "^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 "^1.0.2"
-    which-module "^1.0.0"
+    string-width "^2.0.0"
+    which-module "^2.0.0"
     y18n "^3.2.1"
-    yargs-parser "^5.0.0"
+    yargs-parser "^9.0.2"
 
-yargs@^8.0.2:
-  version "8.0.2"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"
+yargs@^12.0.2:
+  version "12.0.5"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
+  integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
   dependencies:
-    camelcase "^4.1.0"
-    cliui "^3.2.0"
-    decamelize "^1.1.1"
+    cliui "^4.0.0"
+    decamelize "^1.2.0"
+    find-up "^3.0.0"
     get-caller-file "^1.0.1"
-    os-locale "^2.0.0"
-    read-pkg-up "^2.0.0"
+    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"
-    yargs-parser "^7.0.0"
+    y18n "^3.2.1 || ^4.0.0"
+    yargs-parser "^11.1.1"
 
-yargs@^9.0.0:
-  version "9.0.1"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c"
+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"
@@ -7936,12 +9857,3 @@ yargs@^9.0.0:
     which-module "^2.0.0"
     y18n "^3.2.1"
     yargs-parser "^7.0.0"
-
-yargs@~3.10.0:
-  version "3.10.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
-  dependencies:
-    camelcase "^1.0.2"
-    cliui "^2.1.0"
-    decamelize "^1.0.0"
-    window-size "0.1.0"