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 +[](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/). -[](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 @@  ======== +[][releases] [][circleci] [][code_climate] +[][weblate] +[][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: -[][youtube_demo] +[][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? + • + = t("admin.domain_blocks.severity.#{instance.domain_block.severity}") + - if instance.domain_block.reject_media? + • + = t('admin.domain_blocks.rejecting_media') + - if instance.domain_block.reject_reports? + • + = 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 - — - %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)} + %p{ :style => ('margin-bottom: 0' unless current_account&.user&.setting_expand_spoilers) }< + %span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)} %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) + + %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)} + %p{ :style => ('margin-bottom: 0' unless current_account&.user&.setting_expand_spoilers) }< + %span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)} %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><a></code> Ùˆ <code><em></code>. + desc_html: Ùقرة تمهيدية على Ø§Ù„ØµÙØØ© الأولى. ص٠ميزات خادوم ماستدون هذا Ùˆ ما يميّزه عن الآخرين. يمكنك استخدام علامات HTML ØŒ ولا سيما <code><a></code> Ùˆ <code><em></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><a></code> è <code><em></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><a></code> è <code><em></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><a></code> a <code><em></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: "…" + 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><a></code> a <code><em></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: "…" + 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><a></code> og <code><em></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: "...…" 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><a></code> und <code><em></code>. + desc_html: Einleitungsabschnitt auf der Frontseite. Beschreibe, was diese Mastodon-Instanz ausmacht. Du kannst HTML-Tags benutzen, insbesondere <code><a></code> und <code><em></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>< a></code> και <code> < em></code>. + desc_html: Εισαγωγική παÏάγÏαφος στην αÏχική σελίδα. ΠεÏιÎγÏαψε τι κάνει αυτό τον διακομιστή Mastodon διαφοÏετικό και ÏŒ,τι άλλο ενδιαφÎÏον. ΜποÏείς να χÏησιμοποιήσεις HTML tags, συγκεκÏιμÎνα <code>< a></code> και <code> < em></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><a></code> and <code><em></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><a></code> and <code><em></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><a></code> kaj <code><em></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><a></code> kaj <code><em></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><a></code> eta <code><em></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><a></code> eta <code><em></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><a></code> Ùˆ <code><em></code>. + desc_html: معرÙÛŒ کوتاهی Ú©Ù‡ روی ØµÙØÙ‡Ù” اصلی نمایش می‌یابد. دربارهٔ این Ú©Ù‡ Ú†Ù‡ چیزی دربارهٔ این سرور ماستدون ویژه است یا هر چیز مهم دیگری بنویسید. می‌توانید HTML بنویسید، به‌ویژه <code><a></code> Ùˆ <code><em></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><a></code> et <code><em></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><a></code> et <code><em></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><a></code> e <code><em></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><a></code> e <code><em></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> לפלטפרומות המסחריות, מסטודון מ×פשרת ×œ×”×ž× ×¢ ×ž×”×¡×™×›×•× ×™× ×”× ×œ×•×•×™× ×œ×”×¤×§×“×ª התקשורת שלך בידי חברה יחידה. שמת ×ת מבטחך בשרת ×חד — ×œ× ×ž×©× ×” במי בחרת, תמיד ×פשר לדבר ×¢× ×›×œ ש×ר המשתמשי×. לכל מי שרוצה יש ×ת ×”×פשרות ×œ×”×§×™× ×©×¨×ª מסטודון עצמ××™, ולהשתתף ב<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 — 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 — 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><a></code> e <code><em></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><a></code> 㨠<code><em></code>ãŒä½¿ãˆã¾ã™ã€‚ + desc_html: フãƒãƒ³ãƒˆãƒšãƒ¼ã‚¸ã¸ã®è¡¨ç¤ºã«ä½¿ç”¨ã•れる紹介文ã§ã™ã€‚ã“ã®Mastodonインスタンスを特徴付ã‘ã‚‹ã“ã¨ã‚„ãã®ä»–é‡è¦ãªã“ã¨ã‚’記述ã—ã¦ãã ã•ã„。HTMLã‚¿ã‚°ã€ç‰¹ã«<code><a></code> 㨠<code><em></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><a></code> დრ<code><em></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: "…" + 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>를 채íƒí•´, ì—¬ëŸ¬ë¶„ì˜ ëŒ€í™”ê°€ 한 íšŒì‚¬ì— ë…ì ë˜ëŠ” ê²ƒì„ ë°©ì§€í•©ë‹ˆë‹¤. ì‹ ë¢°í• ìˆ˜ 있는 ì¸ìŠ¤í„´ìŠ¤ë¥¼ ì„ íƒí•˜ì„¸ìš” — ì–´ë–¤ ì¸ìŠ¤í„´ìŠ¤ë¥¼ ê³ ë¥´ë”ë¼ë„, ëˆ„êµ¬ì™€ë„ ëŒ€í™”í• ìˆ˜ 있습니다. 누구나 ìžì‹ ë§Œì˜ ë§ˆìŠ¤í† ëˆ ì¸ìŠ¤í„´ìŠ¤ë¥¼ 만들 수 있으며, 아주 매ë„럽게 <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><a></code>, <code><em></code> ê°™ì€ ê²ƒì„ ì‚¬ìš© 가능합니다. + desc_html: í”„ë¡ íŠ¸ 페ì´ì§€ì˜ ì†Œê°œë¬¸ì— ì‚¬ìš© ë©ë‹ˆë‹¤.ì´ ë§ˆìŠ¤í† ëˆ ì„œë²„ì˜ íŠ¹ë³„í•œ ì ë“±ì„ ì„¤ëª…í•˜ì„¸ìš”. HTML 태그, 주로 <code><a></code>, <code><em></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><a></code> en <code><em></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><a></code> en <code><em></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><a></code> e <code><em></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><a></code> e<code><em></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 — 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><a></code> i <code><em></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><a></code> i <code><em></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><a></code> e <code><em></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><a></code> e <code><em></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 предотвращает риÑк монополизации Вашего Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð¹ компанией. Выберите Ñервер, которому Ð’Ñ‹ доверÑете — что бы Ð’Ñ‹ ни выбрали, Ð’Ñ‹ Ñможете общатьÑÑ Ñо вÑеми оÑтальными. Любой может запуÑтить Ñвой ÑобÑтвенный узел 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>< a></code> a <code>< em> </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>< a ></code>, ale tiež <code><></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: "…" 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><a></code> ve <code><em></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> альтернативою комерційним платформам, що дозволÑÑ” уникнути ризиків монополізації вашого ÑÐ¿Ñ–Ð»ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð´Ð½Ñ–Ñ”ÑŽ компанією. Виберіть Ñервер, Ñкому ви довірÑєте — що б ви не вибрали, Ви зможете ÑпілкуватиÑÑŒ з уÑіма іншими. Будь-Ñкий кориÑтувач може запуÑтити влаÑну інÑтанцію 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><a></code> Ñ– <code><em></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: "…" + 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&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 '<del>b</del>' 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 '<script>alert("Hello")</script>' 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><script>alert("Hello")</script></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><img src="javascript:alert('XSS');"></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"